mirror of
https://github.com/elementary/gala.git
synced 2024-11-26 11:25:47 +03:00
wayland: Add Pantheon Shell protocol
Co-authored-by: Leonhard Kargl <leo.kargl@proton.me>
This commit is contained in:
parent
7ac65758ed
commit
c0f377b294
@ -51,6 +51,9 @@ all_doc_target = custom_target(
|
|||||||
'--pkg', 'granite',
|
'--pkg', 'granite',
|
||||||
'--pkg', 'gnome-desktop-3.0',
|
'--pkg', 'gnome-desktop-3.0',
|
||||||
'--pkg', 'gmodule-2.0',
|
'--pkg', 'gmodule-2.0',
|
||||||
|
'--pkg', 'wayland-server',
|
||||||
|
'--pkg', 'pantheon-desktop-shell',
|
||||||
|
'--vapidir=' + join_paths(meson.global_source_root(), 'protocol'),
|
||||||
'-o', '@OUTPUT@',
|
'-o', '@OUTPUT@',
|
||||||
'@INPUT@'
|
'@INPUT@'
|
||||||
],
|
],
|
||||||
|
@ -182,6 +182,7 @@ if get_option('systemd')
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
subdir('data')
|
subdir('data')
|
||||||
|
subdir('protocol')
|
||||||
subdir('lib')
|
subdir('lib')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
subdir('daemon')
|
subdir('daemon')
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
src/Dialogs.vala
|
src/Dialogs.vala
|
||||||
|
src/PantheonShell.vala
|
||||||
src/ScreenshotManager.vala
|
src/ScreenshotManager.vala
|
||||||
src/WindowManager.vala
|
src/WindowManager.vala
|
||||||
daemon/BackgroundMenu.vala
|
daemon/BackgroundMenu.vala
|
||||||
|
32
protocol/meson.build
Normal file
32
protocol/meson.build
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
dep_scanner = dependency('wayland-scanner', native: true)
|
||||||
|
prog_scanner = find_program(dep_scanner.get_variable(pkgconfig: 'wayland_scanner'))
|
||||||
|
|
||||||
|
protocol_file = files('pantheon-desktop-shell-v1.xml')
|
||||||
|
|
||||||
|
pantheon_desktop_shell_sources = []
|
||||||
|
pantheon_desktop_shell_sources += custom_target(
|
||||||
|
'pantheon-desktop-shell-server-protocol.h',
|
||||||
|
command: [ prog_scanner, 'server-header', '@INPUT@', '@OUTPUT@' ],
|
||||||
|
input: protocol_file,
|
||||||
|
output: 'pantheon-desktop-shell-server-protocol.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
output_type = 'private-code'
|
||||||
|
if dep_scanner.version().version_compare('< 1.14.91')
|
||||||
|
output_type = 'code'
|
||||||
|
endif
|
||||||
|
pantheon_desktop_shell_sources += custom_target(
|
||||||
|
'pantheon-desktop-shell-protocol.c',
|
||||||
|
command: [ prog_scanner, output_type, '@INPUT@', '@OUTPUT@' ],
|
||||||
|
input: protocol_file,
|
||||||
|
output: 'pantheon-desktop-shell-protocol.c',
|
||||||
|
)
|
||||||
|
|
||||||
|
pantheon_desktop_shell_dep = declare_dependency(
|
||||||
|
dependencies: [
|
||||||
|
vala.find_library('pantheon-desktop-shell', dirs: meson.current_source_dir()),
|
||||||
|
dependency('wayland-server'),
|
||||||
|
],
|
||||||
|
include_directories: include_directories('.'),
|
||||||
|
sources: pantheon_desktop_shell_sources
|
||||||
|
)
|
115
protocol/pantheon-desktop-shell-v1.xml
Normal file
115
protocol/pantheon-desktop-shell-v1.xml
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="pantheon_shell_v1">
|
||||||
|
<copyright><![CDATA[
|
||||||
|
SPDX-FileCopyrightText: 2023 Corentin Noël <tintou@noel.tf>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
|
]]></copyright>
|
||||||
|
|
||||||
|
<interface name="io_elementary_pantheon_shell_v1" version="1">
|
||||||
|
<description summary="create panel, widget and get more control">
|
||||||
|
This interface is used by the Pantheon Wayland shell to communicate with
|
||||||
|
the compositor.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="get_panel">
|
||||||
|
<description summary="create a panel surface from a surface">
|
||||||
|
Create a panel surface from an existing surface.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="new_id" interface="io_elementary_pantheon_panel_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_widget">
|
||||||
|
<description summary="create a widget surface from a surface">
|
||||||
|
Create a desktop widget surface from an existing surface.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="new_id" interface="io_elementary_pantheon_widget_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_extended_behavior">
|
||||||
|
<description summary="create a desktop-specific surface from a surface">
|
||||||
|
Create a desktop-specific surface from an existing surface.
|
||||||
|
</description>
|
||||||
|
<arg name="output" type="new_id" interface="io_elementary_pantheon_extended_behavior_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="io_elementary_pantheon_panel_v1" version="1">
|
||||||
|
<request name="destroy" type="destructor"/>
|
||||||
|
|
||||||
|
<enum name="anchor">
|
||||||
|
<description summary="anchor">
|
||||||
|
The anchor is a placement hint to the compositor.
|
||||||
|
</description>
|
||||||
|
<entry name="top" value="0" summary="the top edge of the screen"/>
|
||||||
|
<entry name="bottom" value="1" summary="the bottom edge of the screen"/>
|
||||||
|
<entry name="left" value="2" summary="the left edge of the screen"/>
|
||||||
|
<entry name="right" value="3" summary="the right edge of the screen"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<enum name="hide_mode">
|
||||||
|
<description summary="hide mode">
|
||||||
|
How the shell should handle the window.
|
||||||
|
</description>
|
||||||
|
<entry name="never" value="0" summary="make the surface exclusive"/>
|
||||||
|
<entry name="maximized_focus_window" value="1" summary="hide when the focused window is maximized"/>
|
||||||
|
<entry name="overlapping_focus_window" value="2" summary="hide when the focused window overlaps the surface"/>
|
||||||
|
<entry name="overlapping_window" value="3" summary="hide when any window overlaps the surface"/>
|
||||||
|
<entry name="always" value="4" summary="always hide and only show if requested by the user"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="set_anchor">
|
||||||
|
<description summary="set panel edge anchor">
|
||||||
|
Tell the shell which side of the screen the panel is
|
||||||
|
located. This is so that new windows do not overlap the panel
|
||||||
|
and maximized windows maximize properly.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="anchor" type="uint" enum="anchor" summary="anchor"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="focus">
|
||||||
|
<description summary="request keyboard focus">
|
||||||
|
Request keyboard focus, taking it away from any other window.
|
||||||
|
Keyboard focus must always be manually be requested and is
|
||||||
|
- in contrast to normal windows - never automatically granted
|
||||||
|
by the compositor.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_size">
|
||||||
|
<description summary="set size">
|
||||||
|
The given size is only used for exclusive zones and
|
||||||
|
collision tracking for auto hide. By default and if set
|
||||||
|
to -1 the size of the surface is used.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="width" type="int"/>
|
||||||
|
<arg name="height" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_hide_mode">
|
||||||
|
<description summary="set panel hide mode">
|
||||||
|
Tell the shell when to hide the panel.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<arg name="hide_mode" type="uint" enum="hide_mode" summary="hide mode"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="io_elementary_pantheon_widget_v1" version="1">
|
||||||
|
<request name="destroy" type="destructor"/>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="io_elementary_pantheon_extended_behavior_v1" version="1">
|
||||||
|
<request name="destroy" type="destructor"/>
|
||||||
|
<request name="set_keep_above">
|
||||||
|
<description summary="set keep above">
|
||||||
|
Tell the shell to keep the surface above on all workspaces
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
1
protocol/pantheon-desktop-shell.deps
Normal file
1
protocol/pantheon-desktop-shell.deps
Normal file
@ -0,0 +1 @@
|
|||||||
|
wayland-server
|
79
protocol/pantheon-desktop-shell.vapi
Normal file
79
protocol/pantheon-desktop-shell.vapi
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 elementary, Inc. <https://elementary.io>
|
||||||
|
* Copyright 2023 Corentin Noël <tintou@noel.tf>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pantheon.Desktop {
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_shell_v1_interface")]
|
||||||
|
public struct ShellInterface {
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_shell_v1_interface")]
|
||||||
|
public static Wl.Interface iface;
|
||||||
|
public Pantheon.Desktop.GetPanel get_panel;
|
||||||
|
public Pantheon.Desktop.GetWidget get_widget;
|
||||||
|
public Pantheon.Desktop.GetExtendedBehavior get_extended_behavior;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "enum io_elementary_pantheon_panel_v1_anchor", cprefix="IO_ELEMENTARY_PANTHEON_PANEL_V1_ANCHOR_", has_type_id = false)]
|
||||||
|
public enum Anchor {
|
||||||
|
TOP,
|
||||||
|
BOTTOM,
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "enum io_elementary_pantheon_panel_v1_hide_mode", cprefix="IO_ELEMENTARY_PANTHEON_PANEL_V1_HIDE_MODE_", has_type_id = false)]
|
||||||
|
public enum HideMode {
|
||||||
|
NEVER,
|
||||||
|
MAXIMIZED_FOCUS_WINDOW,
|
||||||
|
OVERLAPPING_FOCUS_WINDOW,
|
||||||
|
OVERLAPPING_WINDOW,
|
||||||
|
ALWAYS
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_panel_v1_interface")]
|
||||||
|
public struct PanelInterface {
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_panel_v1_interface")]
|
||||||
|
public static Wl.Interface iface;
|
||||||
|
public Destroy destroy;
|
||||||
|
public SetAnchor set_anchor;
|
||||||
|
public Focus focus;
|
||||||
|
public SetSize set_size;
|
||||||
|
public SetHideMode set_hide_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_widget_v1_interface")]
|
||||||
|
public struct WidgetInterface {
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_widget_v1_interface")]
|
||||||
|
public static Wl.Interface iface;
|
||||||
|
public Destroy destroy;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "struct io_elementary_pantheon_extended_behavior_v1_interface")]
|
||||||
|
public struct ExtendedBehaviorInterface {
|
||||||
|
[CCode (cheader_filename = "pantheon-desktop-shell-server-protocol.h", cname = "io_elementary_pantheon_extended_behavior_v1_interface")]
|
||||||
|
public static Wl.Interface iface;
|
||||||
|
public Destroy destroy;
|
||||||
|
public SetKeepAbove set_keep_above;
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void GetPanel (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void GetWidget (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void GetExtendedBehavior (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void SetAnchor (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Anchor anchor);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void Focus (Wl.Client client, Wl.Resource resource);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void SetSize (Wl.Client client, Wl.Resource resource, int width, int height);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void SetHideMode (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] HideMode hide_mode);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void SetKeepAbove (Wl.Client client, Wl.Resource resource);
|
||||||
|
[CCode (has_target = false, has_typedef = false)]
|
||||||
|
public delegate void Destroy (Wl.Client client, Wl.Resource resource);
|
||||||
|
}
|
@ -76,6 +76,9 @@ namespace Gala {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
ctx.start ();
|
ctx.start ();
|
||||||
|
if (ctx.get_compositor_type () == Meta.CompositorType.WAYLAND) {
|
||||||
|
Gala.init_pantheon_shell (ctx);
|
||||||
|
}
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
stderr.printf ("Failed to start: %s\n", e.message);
|
stderr.printf ("Failed to start: %s\n", e.message);
|
||||||
return Posix.EXIT_FAILURE;
|
return Posix.EXIT_FAILURE;
|
||||||
|
314
src/PantheonShell.vala
Normal file
314
src/PantheonShell.vala
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 elementary, Inc. <https://elementary.io>
|
||||||
|
* Copyright 2023 Corentin Noël <tintou@noel.tf>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Gala {
|
||||||
|
#if !HAS_MUTTER45
|
||||||
|
[Compact]
|
||||||
|
public class FakeMetaWaylandCompositor : GLib.Object {
|
||||||
|
// It is the third field and Vala adds a FakeMetaWaylandCompositorPrivate *priv
|
||||||
|
public Wl.Display wayland_display;
|
||||||
|
|
||||||
|
[CCode (cname = "meta_context_get_wayland_compositor")]
|
||||||
|
public extern static unowned Gala.FakeMetaWaylandCompositor from_context (Meta.Context context);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
public static inline unowned Wl.Display? get_display_from_context (Meta.Context context) {
|
||||||
|
#if HAS_MUTTER45
|
||||||
|
unowned Meta.WaylandCompositor? compositor = context.get_wayland_compositor ();
|
||||||
|
if (compositor == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (Wl.Display) compositor.get_wayland_display ();
|
||||||
|
#else
|
||||||
|
unowned FakeMetaWaylandCompositor compositor = Gala.FakeMetaWaylandCompositor.from_context (context);
|
||||||
|
if (compositor == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return compositor.wayland_display;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pantheon.Desktop.ShellInterface wayland_pantheon_shell_interface;
|
||||||
|
private static Pantheon.Desktop.PanelInterface wayland_pantheon_panel_interface;
|
||||||
|
private static Pantheon.Desktop.WidgetInterface wayland_pantheon_widget_interface;
|
||||||
|
private static Pantheon.Desktop.ExtendedBehaviorInterface wayland_pantheon_extended_behavior_interface;
|
||||||
|
private static Wl.Global shell_global;
|
||||||
|
|
||||||
|
public void init_pantheon_shell (Meta.Context context) {
|
||||||
|
unowned Wl.Display? wl_disp = get_display_from_context (context);
|
||||||
|
if (wl_disp == null) {
|
||||||
|
debug ("Not running under Wayland, no Pantheon Shell protocol");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wayland_pantheon_shell_interface = {
|
||||||
|
get_panel,
|
||||||
|
get_widget,
|
||||||
|
get_extended_behavior,
|
||||||
|
};
|
||||||
|
|
||||||
|
wayland_pantheon_panel_interface = {
|
||||||
|
destroy_panel_surface,
|
||||||
|
set_anchor,
|
||||||
|
focus,
|
||||||
|
set_size,
|
||||||
|
set_hide_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
wayland_pantheon_widget_interface = {
|
||||||
|
destroy_widget_surface,
|
||||||
|
};
|
||||||
|
|
||||||
|
wayland_pantheon_extended_behavior_interface = {
|
||||||
|
destroy_extended_behavior_surface,
|
||||||
|
set_keep_above,
|
||||||
|
};
|
||||||
|
|
||||||
|
PanelSurface.quark = GLib.Quark.from_string ("-gala-wayland-panel-surface-data");
|
||||||
|
|
||||||
|
shell_global = Wl.Global.create (wl_disp, ref Pantheon.Desktop.ShellInterface.iface, 1, (client, version, id) => {
|
||||||
|
unowned var resource = client.create_resource (ref Pantheon.Desktop.ShellInterface.iface, (int) version, id);
|
||||||
|
resource.set_implementation (&wayland_pantheon_shell_interface, null, (res) => {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PanelSurface : GLib.Object {
|
||||||
|
public static GLib.Quark quark = 0;
|
||||||
|
public unowned GLib.Object? wayland_surface;
|
||||||
|
|
||||||
|
public PanelSurface (GLib.Object wayland_surface) {
|
||||||
|
this.wayland_surface = wayland_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PanelSurface () {
|
||||||
|
if (wayland_surface != null) {
|
||||||
|
wayland_surface.steal_qdata<unowned GLib.Object> (quark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void on_wayland_surface_disposed () {
|
||||||
|
wayland_surface = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class WidgetSurface : GLib.Object {
|
||||||
|
public static GLib.Quark quark = 0;
|
||||||
|
public unowned GLib.Object? wayland_surface;
|
||||||
|
|
||||||
|
public WidgetSurface (GLib.Object wayland_surface) {
|
||||||
|
this.wayland_surface = wayland_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
~WidgetSurface () {
|
||||||
|
if (wayland_surface != null) {
|
||||||
|
wayland_surface.steal_qdata<unowned GLib.Object> (quark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void on_wayland_surface_disposed () {
|
||||||
|
wayland_surface = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ExtendedBehaviorSurface : GLib.Object {
|
||||||
|
public static GLib.Quark quark = 0;
|
||||||
|
public unowned GLib.Object? wayland_surface;
|
||||||
|
|
||||||
|
public ExtendedBehaviorSurface (GLib.Object wayland_surface) {
|
||||||
|
this.wayland_surface = wayland_surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ExtendedBehaviorSurface () {
|
||||||
|
if (wayland_surface != null) {
|
||||||
|
wayland_surface.steal_qdata<unowned GLib.Object> (quark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void on_wayland_surface_disposed () {
|
||||||
|
wayland_surface = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unref_obj_on_destroy (Wl.Resource resource) {
|
||||||
|
resource.get_user_data<GLib.Object> ().unref ();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void get_panel (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface_resource) {
|
||||||
|
unowned GLib.Object? wayland_surface = surface_resource.get_user_data<GLib.Object> ();
|
||||||
|
PanelSurface? panel_surface = wayland_surface.get_qdata (PanelSurface.quark);
|
||||||
|
if (panel_surface != null) {
|
||||||
|
surface_resource.post_error (
|
||||||
|
Wl.DisplayError.INVALID_OBJECT,
|
||||||
|
"io_elementary_pantheon_shell_v1_interface::get_panel already requested"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
panel_surface = new PanelSurface (wayland_surface);
|
||||||
|
unowned var panel_resource = client.create_resource (
|
||||||
|
ref Pantheon.Desktop.PanelInterface.iface,
|
||||||
|
resource.get_version (),
|
||||||
|
output
|
||||||
|
);
|
||||||
|
panel_resource.set_implementation (
|
||||||
|
&wayland_pantheon_panel_interface,
|
||||||
|
panel_surface.ref (),
|
||||||
|
unref_obj_on_destroy
|
||||||
|
);
|
||||||
|
wayland_surface.set_qdata_full (
|
||||||
|
PanelSurface.quark,
|
||||||
|
panel_surface,
|
||||||
|
(GLib.DestroyNotify) PanelSurface.on_wayland_surface_disposed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void get_widget (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface_resource) {
|
||||||
|
unowned GLib.Object? wayland_surface = surface_resource.get_user_data<GLib.Object> ();
|
||||||
|
WidgetSurface? widget_surface = wayland_surface.get_qdata (WidgetSurface.quark);
|
||||||
|
if (widget_surface != null) {
|
||||||
|
surface_resource.post_error (
|
||||||
|
Wl.DisplayError.INVALID_OBJECT,
|
||||||
|
"io_elementary_pantheon_shell_v1_interface::get_widget already requested"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
widget_surface = new WidgetSurface (wayland_surface);
|
||||||
|
unowned var widget_resource = client.create_resource (
|
||||||
|
ref Pantheon.Desktop.WidgetInterface.iface,
|
||||||
|
resource.get_version (),
|
||||||
|
output
|
||||||
|
);
|
||||||
|
widget_resource.set_implementation (
|
||||||
|
&wayland_pantheon_widget_interface,
|
||||||
|
widget_surface.ref (),
|
||||||
|
unref_obj_on_destroy
|
||||||
|
);
|
||||||
|
wayland_surface.set_qdata_full (
|
||||||
|
WidgetSurface.quark,
|
||||||
|
widget_surface,
|
||||||
|
(GLib.DestroyNotify) WidgetSurface.on_wayland_surface_disposed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void get_extended_behavior (Wl.Client client, Wl.Resource resource, uint32 output, Wl.Resource surface_resource) {
|
||||||
|
unowned GLib.Object? wayland_surface = surface_resource.get_user_data<GLib.Object> ();
|
||||||
|
ExtendedBehaviorSurface? eb_surface = wayland_surface.get_qdata (ExtendedBehaviorSurface.quark);
|
||||||
|
if (eb_surface != null) {
|
||||||
|
surface_resource.post_error (
|
||||||
|
Wl.DisplayError.INVALID_OBJECT,
|
||||||
|
"io_elementary_pantheon_shell_v1_interface::get_extended_behavior already requested"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
eb_surface = new ExtendedBehaviorSurface (wayland_surface);
|
||||||
|
unowned var eb_resource = client.create_resource (
|
||||||
|
ref Pantheon.Desktop.ExtendedBehaviorInterface.iface,
|
||||||
|
resource.get_version (),
|
||||||
|
output
|
||||||
|
);
|
||||||
|
eb_resource.set_implementation (
|
||||||
|
&wayland_pantheon_extended_behavior_interface,
|
||||||
|
eb_surface.ref (),
|
||||||
|
unref_obj_on_destroy
|
||||||
|
);
|
||||||
|
wayland_surface.set_qdata_full (
|
||||||
|
ExtendedBehaviorSurface.quark,
|
||||||
|
eb_surface,
|
||||||
|
(GLib.DestroyNotify) ExtendedBehaviorSurface.on_wayland_surface_disposed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void set_anchor (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Pantheon.Desktop.Anchor anchor) {
|
||||||
|
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
|
||||||
|
if (panel_surface.wayland_surface == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meta.Window? window;
|
||||||
|
panel_surface.wayland_surface.get ("window", out window, null);
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void focus (Wl.Client client, Wl.Resource resource) {
|
||||||
|
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
|
||||||
|
if (panel_surface.wayland_surface == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meta.Window? window;
|
||||||
|
panel_surface.wayland_surface.get ("window", out window, null);
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.focus (window.get_display ().get_current_time ());
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void set_size (Wl.Client client, Wl.Resource resource, int width, int height) {
|
||||||
|
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
|
||||||
|
if (panel_surface.wayland_surface == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meta.Window? window;
|
||||||
|
panel_surface.wayland_surface.get ("window", out window, null);
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void set_hide_mode (Wl.Client client, Wl.Resource resource, [CCode (type = "uint32_t")] Pantheon.Desktop.HideMode hide_mode) {
|
||||||
|
unowned PanelSurface? panel_surface = resource.get_user_data<PanelSurface> ();
|
||||||
|
if (panel_surface.wayland_surface == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meta.Window? window;
|
||||||
|
panel_surface.wayland_surface.get ("window", out window, null);
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void set_keep_above (Wl.Client client, Wl.Resource resource) {
|
||||||
|
unowned ExtendedBehaviorSurface? eb_surface = resource.get_user_data<ExtendedBehaviorSurface> ();
|
||||||
|
if (eb_surface.wayland_surface == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meta.Window? window;
|
||||||
|
eb_surface.wayland_surface.get ("window", out window, null);
|
||||||
|
if (window == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.make_above ();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void destroy_panel_surface (Wl.Client client, Wl.Resource resource) {
|
||||||
|
resource.destroy ();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void destroy_widget_surface (Wl.Client client, Wl.Resource resource) {
|
||||||
|
resource.destroy ();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void destroy_extended_behavior_surface (Wl.Client client, Wl.Resource resource) {
|
||||||
|
resource.destroy ();
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ gala_bin_sources = files(
|
|||||||
'Main.vala',
|
'Main.vala',
|
||||||
'MediaFeedback.vala',
|
'MediaFeedback.vala',
|
||||||
'NotificationStack.vala',
|
'NotificationStack.vala',
|
||||||
|
'PantheonShell.vala',
|
||||||
'PluginManager.vala',
|
'PluginManager.vala',
|
||||||
'ScreenSaverManager.vala',
|
'ScreenSaverManager.vala',
|
||||||
'ScreenshotManager.vala',
|
'ScreenshotManager.vala',
|
||||||
@ -69,7 +70,7 @@ gala_bin_sources = files(
|
|||||||
gala_bin = executable(
|
gala_bin = executable(
|
||||||
'gala',
|
'gala',
|
||||||
gala_bin_sources,
|
gala_bin_sources,
|
||||||
dependencies: [gala_dep, gala_base_dep],
|
dependencies: [gala_dep, gala_base_dep, pantheon_desktop_shell_dep],
|
||||||
include_directories: config_inc_dir,
|
include_directories: config_inc_dir,
|
||||||
install_rpath: mutter_typelib_dir,
|
install_rpath: mutter_typelib_dir,
|
||||||
install: true,
|
install: true,
|
||||||
|
1
vapi/wayland-server.deps
Normal file
1
vapi/wayland-server.deps
Normal file
@ -0,0 +1 @@
|
|||||||
|
posix
|
125
vapi/wayland-server.vapi
Normal file
125
vapi/wayland-server.vapi
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/* wayland-server.vapi
|
||||||
|
*
|
||||||
|
* Copyright 2022 Corentin Noël <corentin.noel@collabora.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
* a copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial
|
||||||
|
* portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||||
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Corentin Noël <corentin.noel@collabora.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
[CCode (cprefix = "wl_", lower_case_cprefix = "wl_", cheader_filename = "wayland-server.h")]
|
||||||
|
namespace Wl {
|
||||||
|
[Compact]
|
||||||
|
[CCode (cname = "struct wl_display", free_function = "wl_display_destroy")]
|
||||||
|
public class Display {
|
||||||
|
[CCode (cname = "wl_display_create")]
|
||||||
|
public Display ();
|
||||||
|
public int add_socket (string name);
|
||||||
|
public unowned string add_socket_auto ();
|
||||||
|
public int add_socket_fd (int sock_fd);
|
||||||
|
public void terminate ();
|
||||||
|
public void run ();
|
||||||
|
public void flush_clients ();
|
||||||
|
public void destroy_clients ();
|
||||||
|
public uint32 get_serial ();
|
||||||
|
public uint32 next_serial ();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Compact]
|
||||||
|
[CCode (cname = "struct wl_client", free_function = "wl_client_destroy")]
|
||||||
|
public class Client {
|
||||||
|
[CCode (cname = "wl_client_create")]
|
||||||
|
public Client (Wl.Display display, int fd);
|
||||||
|
public void flush ();
|
||||||
|
public void get_credentials (out Posix.pid_t pid, out Posix.uid_t uid, out Posix.gid_t gid);
|
||||||
|
public int get_fd ();
|
||||||
|
public unowned Wl.Display get_display ();
|
||||||
|
[CCode (cname = "wl_resource_create")]
|
||||||
|
public unowned Wl.Resource? create_resource (ref Wl.Interface interface, int version, uint32 id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Compact]
|
||||||
|
[CCode (cname = "struct wl_resource", free_function = "wl_resource_destroy")]
|
||||||
|
public class Resource {
|
||||||
|
public uint32 get_id ();
|
||||||
|
public unowned Wl.Client get_client ();
|
||||||
|
[CCode (simple_generics = true)]
|
||||||
|
public void set_user_data<T> (T? data);
|
||||||
|
[CCode (simple_generics = true)]
|
||||||
|
public unowned T? get_user_data<T> ();
|
||||||
|
public int get_version ();
|
||||||
|
public unowned string get_class ();
|
||||||
|
public void destroy ();
|
||||||
|
public void set_implementation (void* implementation, void* data, [CCode (delegate_target = false)] ResourceDestroyFunc destroy);
|
||||||
|
[PrintfFormat]
|
||||||
|
public void post_error(uint32 code, string format, ...);
|
||||||
|
}
|
||||||
|
[Compact]
|
||||||
|
[CCode (cname = "struct wl_interface")]
|
||||||
|
public class Interface {
|
||||||
|
public string name;
|
||||||
|
public int version;
|
||||||
|
[CCode (array_length = "method_count")]
|
||||||
|
public Wl.Message[] methods;
|
||||||
|
[CCode (array_length = "event_count")]
|
||||||
|
public Wl.Message[] events;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Compact]
|
||||||
|
[CCode (cname = "struct wl_message")]
|
||||||
|
public class Message {
|
||||||
|
public string name;
|
||||||
|
public string signature;
|
||||||
|
[CCode (array_length = false)]
|
||||||
|
public Wl.Interface?[] types;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Compact]
|
||||||
|
[CCode (cname = "struct wl_global", free_function = "wl_global_destroy")]
|
||||||
|
public class Global {
|
||||||
|
[CCode (cname = "wl_global_create")]
|
||||||
|
public static Wl.Global? create (Wl.Display display, ref Wl.Interface interface, int version, [CCode (delegate_target_pos = 3.9) ] Wl.GlobalBindFunc bind);
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (cheader_filename = "wayland-server-protocol.h", cname = "enum wl_display_error", cprefix="WL_DISPLAY_ERROR_", has_type_id = false)]
|
||||||
|
public enum DisplayError {
|
||||||
|
INVALID_OBJECT,
|
||||||
|
INVALID_METHOD,
|
||||||
|
NO_MEMORY,
|
||||||
|
IMPLEMENTATION,
|
||||||
|
}
|
||||||
|
|
||||||
|
[CCode (cname = "wl_global_bind_func_t", instance_pos = 1.9)]
|
||||||
|
public delegate void GlobalBindFunc (Wl.Client client, uint32 version, uint32 id);
|
||||||
|
[CCode (cname = "wl_resource_destroy_func_t", has_target = false)]
|
||||||
|
public delegate void ResourceDestroyFunc (Wl.Resource resource);
|
||||||
|
[CCode (cname = "WAYLAND_VERSION_MAJOR")]
|
||||||
|
public const int VERSION_MAJOR;
|
||||||
|
[CCode (cname = "WAYLAND_VERSION_MINOR")]
|
||||||
|
public const int VERSION_MINOR;
|
||||||
|
[CCode (cname = "WAYLAND_VERSION_MICRO")]
|
||||||
|
public const int VERSION_MICRO;
|
||||||
|
[CCode (cname = "WAYLAND_VERSION")]
|
||||||
|
public const string VERSION;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user