commit 3678412fc56ee3f893163d164125fdd85ba00432 Author: pancakes Date: Mon Aug 25 20:02:31 2025 +1000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..add57be --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +/packages/ +riderModule.iml +/_ReSharper.Caches/ \ No newline at end of file diff --git a/.idea/.idea.ZwlrLayerShell/.idea/.gitignore b/.idea/.idea.ZwlrLayerShell/.idea/.gitignore new file mode 100644 index 0000000..2ab285f --- /dev/null +++ b/.idea/.idea.ZwlrLayerShell/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/contentModel.xml +/projectSettingsUpdater.xml +/.idea.ZwlrLayerShell.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.ZwlrLayerShell/.idea/encodings.xml b/.idea/.idea.ZwlrLayerShell/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.ZwlrLayerShell/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.ZwlrLayerShell/.idea/indexLayout.xml b/.idea/.idea.ZwlrLayerShell/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.ZwlrLayerShell/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.ZwlrLayerShell/.idea/vcs.xml b/.idea/.idea.ZwlrLayerShell/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.ZwlrLayerShell/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ZwlrLayerShell.sln b/ZwlrLayerShell.sln new file mode 100644 index 0000000..958fd0c --- /dev/null +++ b/ZwlrLayerShell.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZwlrLayerShell", "ZwlrLayerShell\ZwlrLayerShell.csproj", "{1FF15866-C974-4CDA-9D7B-D703537BBB66}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1FF15866-C974-4CDA-9D7B-D703537BBB66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1FF15866-C974-4CDA-9D7B-D703537BBB66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1FF15866-C974-4CDA-9D7B-D703537BBB66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1FF15866-C974-4CDA-9D7B-D703537BBB66}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/ZwlrLayerShell/LayerShell.cs b/ZwlrLayerShell/LayerShell.cs new file mode 100644 index 0000000..c7a9131 --- /dev/null +++ b/ZwlrLayerShell/LayerShell.cs @@ -0,0 +1,313 @@ +using System.Runtime.InteropServices; +using Gtk; +using Monitor = Gdk.Monitor; + +namespace ZwlrLayerShell; + +/// +/// C# bindings for the gtk4-layer-shell library for use with GirCore.Gtk-4.0. This should be linked before libwayland-client such as by running before creating the application. +/// +/// +/// if (!LayerShell.IsSupported()) { +/// return; +/// } +/// +/// var application = Application.New("com.example.GtkApplication", Gio.ApplicationFlags.None); +/// application.Run(); +/// +/// +public static class LayerShell +{ + [DllImport("gtk4-layer-shell")] + static extern uint gtk_layer_get_major_version(); + + [DllImport("gtk4-layer-shell")] + static extern uint gtk_layer_get_minor_version(); + + [DllImport("gtk4-layer-shell")] + static extern uint gtk_layer_get_micro_version(); + + /// + /// Get the version of the gtk4-layer-shell library being used. + /// + /// Major, minor, and micro version numbers + public static (uint, uint, uint) GetLibraryVersion() + { + return (gtk_layer_get_major_version(), gtk_layer_get_minor_version(), gtk_layer_get_micro_version()); + } + + [DllImport("gtk4-layer-shell")] + static extern bool gtk_layer_is_supported(); + + /// + /// Checks if running on a Wayland compositor that supports the zwlr_layer_shell_v1 extension. + /// + public static bool IsSupported() => gtk_layer_is_supported(); + + [DllImport("gtk4-layer-shell")] + static extern uint gtk_layer_get_protocol_version(); + + /// + /// Get the version of the zwlr_layer_shell_v1 being used. + /// + /// Version number + public static uint GetProtocolVersion() => gtk_layer_get_protocol_version(); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_init_for_window(IntPtr window); + + /// + /// Assigns the layer_surface role to a GTK window. + /// + /// GTK window to initialzie + public static void InitForWindow(Window window) => + gtk_layer_init_for_window(window.Handle.DangerousGetHandle()); + + [DllImport("gtk4-layer-shell")] + static extern bool gtk_layer_is_layer_window(IntPtr window); + + /// + /// Check if the window has been initialized with the layer_surface role. + /// + /// GTK window + /// Whether the window is a layer_surface + public static bool IsLayerWindow(Window window) => gtk_layer_is_layer_window(window.Handle.DangerousGetHandle()); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_set_namespace(IntPtr window, string nameSpace); + + /// + /// Set the namespace for the window. + /// + /// GTK window + /// Namespace to set + public static void SetNamespace(Window window, string nameSpace) => + gtk_layer_set_namespace(window.Handle.DangerousGetHandle(), nameSpace); + + [DllImport("gtk4-layer-shell")] + static extern string gtk_layer_get_namespace(IntPtr window); + + /// + /// Get the namespace of the window. + /// + /// GTK window + /// Namespace of the window or "gtk4-layer-shell" if none is set + public static string GetNamespace(Window window) => gtk_layer_get_namespace(window.Handle.DangerousGetHandle()); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_set_layer(IntPtr window, Layer layer); + + /// + /// Set the layer of the window. + /// + /// GTK window + /// zwlr_layer_shell_v1::layer + public static void SetLayer(Window window, Layer layer) => + gtk_layer_set_layer(window.Handle.DangerousGetHandle(), layer); + + [DllImport("gtk4-layer-shell")] + static extern Layer gtk_layer_get_layer(IntPtr window); + + /// + /// Get the current layer of the window. + /// + /// GTK window + /// Current zwlr_layer_shell_v1::layer + public static Layer GetLayer(Window window) => gtk_layer_get_layer(window.Handle.DangerousGetHandle()); + + [DllImport("gtk4-layer-shell")] + static extern Layer gtk_layer_set_monitor(IntPtr window, IntPtr? monitor); + + /// + /// Set the output the window should be displayed on. + /// + /// GTK window + /// GDK monitor or null to let the compositor decide + public static void SetMonitor(Window window, Monitor? monitor) => + gtk_layer_set_monitor(window.Handle.DangerousGetHandle(), monitor?.Handle.DangerousGetHandle()); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_set_anchor(IntPtr window, Edge edge, bool anchorToEdge); + + /// + /// Set an output edge anchor for the window. + /// + /// GTK window + /// zwlr_layer_shell_v1::edge + /// Whether the window should be anchored + public static void SetAnchor(Window window, Edge edge, bool anchorToEdge) => + gtk_layer_set_anchor(window.Handle.DangerousGetHandle(), edge, anchorToEdge); + + [DllImport("gtk4-layer-shell")] + static extern bool gtk_layer_get_anchor(IntPtr window, Edge edge); + + /// + /// Get the edge anchor for the window. + /// + /// GTK window + /// zwlr_layer_shell_v1::edge + /// Whether the window is anchored to the edge + public static bool GetAnchor(Window window, Edge edge) => + gtk_layer_get_anchor(window.Handle.DangerousGetHandle(), edge); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_set_margin(IntPtr window, Edge edge, int marginSize); + + /// + /// Set the margin for an edge of the window. + /// + /// GTK window + /// zwlr_layer_shell_v1::edge + /// Size in pixels + public static void SetMargin(Window window, Edge edge, int marginSize) => + gtk_layer_set_margin(window.Handle.DangerousGetHandle(), edge, marginSize); + + /// + /// Set the margin for all edges of the window. + /// + /// GTK window + /// Size in pixels + public static void SetMargin(Window window, int marginSize) + { + gtk_layer_set_margin(window.Handle.DangerousGetHandle(), Edge.Left, marginSize); + gtk_layer_set_margin(window.Handle.DangerousGetHandle(), Edge.Right, marginSize); + gtk_layer_set_margin(window.Handle.DangerousGetHandle(), Edge.Top, marginSize); + gtk_layer_set_margin(window.Handle.DangerousGetHandle(), Edge.Bottom, marginSize); + } + + [DllImport("gtk4-layer-shell")] + static extern int gtk_layer_get_margin(IntPtr window, Edge edge); + + /// + /// Get the margin for the edge of the window. + /// + /// GTK window + /// zwlr_layer_shell_v1::edge + /// Size in pixels + public static int GetMargin(Window window, Edge edge) => + gtk_layer_get_margin(window.Handle.DangerousGetHandle(), edge); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_set_exclusive_zone(IntPtr window, int exclusiveZone); + + /// + /// Set the window's exclusive zone. The exclusive zone is a region under the window where the compositor shouldn't place other windows. + /// + /// + /// + public static void SetExclusiveZone(Window window, int exclusiveZone) => + gtk_layer_set_exclusive_zone(window.Handle.DangerousGetHandle(), exclusiveZone); + + [DllImport("gtk4-layer-shell")] + static extern int gtk_layer_get_exclusive_zone(IntPtr window); + + /// + /// Get the window's exclusive zone. + /// + /// GTK window + /// Exclusive zone + public static int GetExclusiveZone(Window window) => + gtk_layer_get_exclusive_zone(window.Handle.DangerousGetHandle()); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_auto_exclusive_zone_enable(IntPtr window); + + /// + /// Enable or disable the window's exclusive zone automatically being set to the size of the window + margins. The exclusive zone is a region under the window where the compositor shouldn't place other windows. + /// + /// GTK window + /// Whether to enable auto exclusive zone + public static void SetAutoExclusiveZone(Window window, bool enable = true) + { + if (enable) + { + gtk_layer_auto_exclusive_zone_enable(window.Handle.DangerousGetHandle()); + } + else if (gtk_layer_auto_exclusive_zone_is_enabled(window.Handle.DangerousGetHandle())) + { + gtk_layer_set_exclusive_zone(window.Handle.DangerousGetHandle(), 0); + } + } + + [DllImport("gtk4-layer-shell")] + static extern bool gtk_layer_auto_exclusive_zone_is_enabled(IntPtr window); + + /// + /// Get the window's auto exclusive zone. + /// + /// GTK window + /// Whether auto exclusive zone is enabled + public static bool GetAutoExclusiveZone(Window window) => + gtk_layer_auto_exclusive_zone_is_enabled(window.Handle.DangerousGetHandle()); + + [DllImport("gtk4-layer-shell")] + static extern void gtk_layer_set_keyboard_mode(IntPtr window, KeyboardMode keyboardMode); + + /// + /// Set the keyboard mode of the window. + /// + /// GTK window + /// zwlr_layer_shell_v1::keyboard_interactivity + public static void SetKeyboardMode(Window window, KeyboardMode keyboardMode) => + gtk_layer_set_keyboard_mode(window.Handle.DangerousGetHandle(), keyboardMode); + + [DllImport("gtk4-layer-shell")] + static extern KeyboardMode gtk_layer_get_keyboard_mode(IntPtr window); + + /// + /// Get the current keyboard mode of the window. + /// + /// GTK window + /// Current zwlr_layer_shell_v1::keyboard_interactivity + public static KeyboardMode GetKeyboardMode(Window window) => + gtk_layer_get_keyboard_mode(window.Handle.DangerousGetHandle()); +} + +public enum Layer +{ + /// + /// The background layer. + /// + Background = 0, + + /// + /// Behind most windows but above the background layer. + /// + Bottom = 1, + + /// + /// Above most windows but below fullscreen windows. + /// + Top = 2, + + /// + /// Above all layers and fullscreen windows. + /// + Overlay = 3, +} + +public enum Edge +{ + Left = 0, + Right = 1, + Top = 2, + Bottom = 3, +} + +public enum KeyboardMode +{ + /// + /// This window should not receive keyboard inputs. + /// + None = 0, + + /// + /// This window should have exclusive focus on top or overlay layers. + /// + Exclusive = 1, + + /// + /// Users should be able to focus or unfocus on demand. Not supported for protocol version < 4. + /// + OnDemand = 2, +} \ No newline at end of file diff --git a/ZwlrLayerShell/ZwlrLayerShell.csproj b/ZwlrLayerShell/ZwlrLayerShell.csproj new file mode 100644 index 0000000..c7449d4 --- /dev/null +++ b/ZwlrLayerShell/ZwlrLayerShell.csproj @@ -0,0 +1,13 @@ + + + + net9.0 + enable + enable + + + + + + +