Initial commit

This commit is contained in:
pancakes 2025-08-25 20:02:31 +10:00
commit 3678412fc5
Signed by: pancakes
SSH key fingerprint: SHA256:yrp4c4hhaPoPG07fb4QyQIgAdlbUdsJvUAydJEWnfTw
8 changed files with 378 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/

13
.idea/.idea.ZwlrLayerShell/.idea/.gitignore generated vendored Normal file
View file

@ -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

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

16
ZwlrLayerShell.sln Normal file
View file

@ -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

View file

@ -0,0 +1,313 @@
using System.Runtime.InteropServices;
using Gtk;
using Monitor = Gdk.Monitor;
namespace ZwlrLayerShell;
/// <summary>
/// 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 <see cref="IsSupported"/> before creating the application.
/// </summary>
/// <code>
/// if (!LayerShell.IsSupported()) {
/// return;
/// }
///
/// var application = Application.New("com.example.GtkApplication", Gio.ApplicationFlags.None);
/// application.Run();
/// </code>
/// <seealso href="https://wayland.app/protocols/wlr-layer-shell-unstable-v1"/>
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();
/// <summary>
/// Get the version of the gtk4-layer-shell library being used.
/// </summary>
/// <returns>Major, minor, and micro version numbers</returns>
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();
/// <summary>
/// Checks if running on a Wayland compositor that supports the zwlr_layer_shell_v1 extension.
/// </summary>
public static bool IsSupported() => gtk_layer_is_supported();
[DllImport("gtk4-layer-shell")]
static extern uint gtk_layer_get_protocol_version();
/// <summary>
/// Get the version of the zwlr_layer_shell_v1 being used.
/// </summary>
/// <returns>Version number</returns>
public static uint GetProtocolVersion() => gtk_layer_get_protocol_version();
[DllImport("gtk4-layer-shell")]
static extern void gtk_layer_init_for_window(IntPtr window);
/// <summary>
/// Assigns the layer_surface role to a GTK window.
/// </summary>
/// <param name="window">GTK window to initialzie</param>
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);
/// <summary>
/// Check if the window has been initialized with the layer_surface role.
/// </summary>
/// <param name="window">GTK window</param>
/// <returns>Whether the window is a layer_surface</returns>
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);
/// <summary>
/// Set the namespace for the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="nameSpace">Namespace to set</param>
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);
/// <summary>
/// Get the namespace of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <returns>Namespace of the window or "gtk4-layer-shell" if none is set</returns>
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);
/// <summary>
/// Set the layer of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="layer">zwlr_layer_shell_v1::layer</param>
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);
/// <summary>
/// Get the current layer of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <returns>Current zwlr_layer_shell_v1::layer</returns>
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);
/// <summary>
/// Set the output the window should be displayed on.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="monitor">GDK monitor or null to let the compositor decide</param>
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);
/// <summary>
/// Set an output edge anchor for the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="edge">zwlr_layer_shell_v1::edge</param>
/// <param name="anchorToEdge">Whether the window should be anchored</param>
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);
/// <summary>
/// Get the edge anchor for the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="edge">zwlr_layer_shell_v1::edge</param>
/// <returns>Whether the window is anchored to the edge</returns>
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);
/// <summary>
/// Set the margin for an edge of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="edge">zwlr_layer_shell_v1::edge</param>
/// <param name="marginSize">Size in pixels</param>
public static void SetMargin(Window window, Edge edge, int marginSize) =>
gtk_layer_set_margin(window.Handle.DangerousGetHandle(), edge, marginSize);
/// <summary>
/// Set the margin for all edges of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="marginSize">Size in pixels</param>
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);
/// <summary>
/// Get the margin for the edge of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="edge">zwlr_layer_shell_v1::edge</param>
/// <returns>Size in pixels</returns>
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);
/// <summary>
/// Set the window's exclusive zone. The exclusive zone is a region under the window where the compositor shouldn't place other windows.
/// </summary>
/// <param name="window"></param>
/// <param name="exclusiveZone"></param>
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);
/// <summary>
/// Get the window's exclusive zone.
/// </summary>
/// <param name="window">GTK window</param>
/// <returns>Exclusive zone</returns>
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);
/// <summary>
/// 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.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="enable">Whether to enable auto exclusive zone</param>
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);
/// <summary>
/// Get the window's auto exclusive zone.
/// </summary>
/// <param name="window">GTK window</param>
/// <returns>Whether auto exclusive zone is enabled</returns>
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);
/// <summary>
/// Set the keyboard mode of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <param name="keyboardMode">zwlr_layer_shell_v1::keyboard_interactivity</param>
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);
/// <summary>
/// Get the current keyboard mode of the window.
/// </summary>
/// <param name="window">GTK window</param>
/// <returns>Current zwlr_layer_shell_v1::keyboard_interactivity</returns>
public static KeyboardMode GetKeyboardMode(Window window) =>
gtk_layer_get_keyboard_mode(window.Handle.DangerousGetHandle());
}
public enum Layer
{
/// <summary>
/// The background layer.
/// </summary>
Background = 0,
/// <summary>
/// Behind most windows but above the background layer.
/// </summary>
Bottom = 1,
/// <summary>
/// Above most windows but below fullscreen windows.
/// </summary>
Top = 2,
/// <summary>
/// Above all layers and fullscreen windows.
/// </summary>
Overlay = 3,
}
public enum Edge
{
Left = 0,
Right = 1,
Top = 2,
Bottom = 3,
}
public enum KeyboardMode
{
/// <summary>
/// This window should not receive keyboard inputs.
/// </summary>
None = 0,
/// <summary>
/// This window should have exclusive focus on top or overlay layers.
/// </summary>
Exclusive = 1,
/// <summary>
/// Users should be able to focus or unfocus on demand. Not supported for protocol version &lt; 4.
/// </summary>
OnDemand = 2,
}

View file

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GirCore.Gtk-4.0" Version="0.6.3" />
</ItemGroup>
</Project>