diff options
author | kotontrion <[email protected]> | 2024-09-24 10:47:14 +0200 |
---|---|---|
committer | kotontrion <[email protected]> | 2024-09-24 10:47:14 +0200 |
commit | 122112c320e62e52b3f0acc5d03c445c44bd8c4c (patch) | |
tree | 5fd80f779b938e767595f5ad37ecf87e7799a717 /core | |
parent | ba7d92df104f374a3796c0c95f3a9cda04976f6a (diff) |
core: add window inhibit property
Diffstat (limited to 'core')
-rw-r--r-- | core/meson.build | 2 | ||||
-rw-r--r-- | core/src/idle-inhibit.c | 124 | ||||
-rw-r--r-- | core/src/idle-inhibit.h | 22 | ||||
-rw-r--r-- | core/src/meson.build | 37 | ||||
-rw-r--r-- | core/src/widget/window.vala | 21 | ||||
-rw-r--r-- | core/vapi/AstalInhibitManager.vapi | 13 |
6 files changed, 218 insertions, 1 deletions
diff --git a/core/meson.build b/core/meson.build index 12b4f1d..f25b5a0 100644 --- a/core/meson.build +++ b/core/meson.build @@ -15,6 +15,8 @@ prefix = get_option('prefix') libdir = get_option('prefix') / get_option('libdir') pkgdatadir = prefix / get_option('datadir') / 'astal' +vapi_dir = meson.current_source_dir() / 'vapi' +add_project_arguments(['--vapidir', vapi_dir], language: 'vala') assert( get_option('lib') or get_option('cli'), diff --git a/core/src/idle-inhibit.c b/core/src/idle-inhibit.c new file mode 100644 index 0000000..b08efd7 --- /dev/null +++ b/core/src/idle-inhibit.c @@ -0,0 +1,124 @@ +#include <gio/gio.h> +#include <wayland-client-protocol.h> +#include <wayland-client.h> +#include <gtk/gtk.h> +#include <gdk/gdkwayland.h> + +#include "idle-inhibit.h" +#include "gdk/gdk.h" +#include "glib-object.h" +#include "glib.h" +#include "idle-inhibit-unstable-v1-client.h" + + +struct _AstalInhibitManager { + GObject parent_instance; +}; + +typedef struct { + gboolean init; + struct wl_registry* wl_registry; + struct wl_display* display; + struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager; +} AstalInhibitManagerPrivate; + + +G_DEFINE_TYPE_WITH_PRIVATE(AstalInhibitManager, astal_inhibit_manager, G_TYPE_OBJECT) + +void astal_inhibitor_free(AstalInhibitor* inhibitor) { + g_print("free inhibitor\n"); + g_assert_nonnull(inhibitor); + zwp_idle_inhibitor_v1_destroy(inhibitor); +} + +AstalInhibitor* astal_inhibit_manager_inhibit(AstalInhibitManager *self, GtkWindow *window) { + AstalInhibitManagerPrivate* priv = astal_inhibit_manager_get_instance_private(self); + g_assert_true(priv->init); + GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(window)); + struct wl_surface *surface = gdk_wayland_window_get_wl_surface(gdk_window); + return zwp_idle_inhibit_manager_v1_create_inhibitor(priv->idle_inhibit_manager, surface); +} + +static void global_registry_handler(void* data, struct wl_registry* registry, uint32_t id, + const char* interface, uint32_t version) { + AstalInhibitManager* self = ASTAL_INHIBIT_MANAGER(data); + AstalInhibitManagerPrivate* priv = astal_inhibit_manager_get_instance_private(self); + + if (strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name) == 0) { + priv->idle_inhibit_manager = + wl_registry_bind(registry, id, &zwp_idle_inhibit_manager_v1_interface, 1); + } + +} + +static void global_registry_remover(void* data, struct wl_registry* registry, uint32_t id) { + //neither inhibit_manager nor inhibitor is going to be removed by the compositor, so we don't need do anything here. +} + +static const struct wl_registry_listener registry_listener = {global_registry_handler, + global_registry_remover}; + + +static gboolean astal_inhibit_manager_wayland_init(AstalInhibitManager *self) { + + AstalInhibitManagerPrivate* priv = astal_inhibit_manager_get_instance_private(self); + + if (priv->init) return TRUE; + + GdkDisplay *gdk_display = gdk_display_get_default(); + priv->display = gdk_wayland_display_get_wl_display(gdk_display); + + priv->wl_registry = wl_display_get_registry(priv->display); + wl_registry_add_listener(priv->wl_registry, ®istry_listener, self); + + wl_display_roundtrip(priv->display); + + if (priv->idle_inhibit_manager == NULL) { + g_critical("Can not connect idle inhibitor protocol"); + return FALSE; + } + + priv->init = TRUE; + return TRUE; +} + +AstalInhibitManager* astal_inhibit_manager_get_default() { + static AstalInhibitManager* self = NULL; + + if (self == NULL) { + self = g_object_new(ASTAL_TYPE_INHIBIT_MANAGER, NULL); + if(!astal_inhibit_manager_wayland_init(self)) { + g_object_unref(self); + self = NULL; + } + } + + return self; +} + +static void astal_inhibit_manager_init(AstalInhibitManager* self) { + AstalInhibitManagerPrivate* priv = astal_inhibit_manager_get_instance_private(self); + priv->init = FALSE; + priv->display = NULL; + priv->wl_registry = NULL; + priv->idle_inhibit_manager = NULL; +} + +static void astal_inhibit_manager_finalize(GObject* object) { + + AstalInhibitManager* self = ASTAL_INHIBIT_MANAGER(object); + AstalInhibitManagerPrivate* priv = astal_inhibit_manager_get_instance_private(self); + + if (priv->display != NULL) wl_display_roundtrip(priv->display); + + if (priv->wl_registry != NULL) wl_registry_destroy(priv->wl_registry); + if (priv->idle_inhibit_manager != NULL) zwp_idle_inhibit_manager_v1_destroy(priv->idle_inhibit_manager); + + G_OBJECT_CLASS(astal_inhibit_manager_parent_class)->finalize(object); +} + +static void astal_inhibit_manager_class_init(AstalInhibitManagerClass* class) { + GObjectClass* object_class = G_OBJECT_CLASS(class); + object_class->finalize = astal_inhibit_manager_finalize; + +} diff --git a/core/src/idle-inhibit.h b/core/src/idle-inhibit.h new file mode 100644 index 0000000..a342f52 --- /dev/null +++ b/core/src/idle-inhibit.h @@ -0,0 +1,22 @@ +#ifndef ASTAL_IDLE_INHIBITOR_H +#define ASTAL_IDLE_INHIBITOR_H + +#include <glib-object.h> +#include <gtk/gtk.h> +#include "idle-inhibit-unstable-v1-client.h" + +G_BEGIN_DECLS + +#define ASTAL_TYPE_INHIBIT_MANAGER (astal_inhibit_manager_get_type()) + +G_DECLARE_FINAL_TYPE(AstalInhibitManager, astal_inhibit_manager, ASTAL, INHIBIT_MANAGER, GObject) + +typedef struct zwp_idle_inhibitor_v1 AstalInhibitor; +void astal_inhibitor_free(AstalInhibitor* inhibitor); + +AstalInhibitManager* astal_inhibit_manager_get_default(); +AstalInhibitor* astal_inhibit_manager_inhibit(AstalInhibitManager *self, GtkWindow *window); + +G_END_DECLS + +#endif // !ASTAL_IDLE_INHIBITOR_H diff --git a/core/src/meson.build b/core/src/meson.build index d7d3871..11839f1 100644 --- a/core/src/meson.build +++ b/core/src/meson.build @@ -22,10 +22,41 @@ pkgconfig_deps = [ dependency('gtk+-3.0'), dependency('gdk-pixbuf-2.0'), dependency('gtk-layer-shell-0'), + dependency('wayland-client'), ] deps = pkgconfig_deps + meson.get_compiler('c').find_library('m') + +wayland_protos = dependency('wayland-protocols') +wayland_scanner = find_program('wayland-scanner') + +wl_protocol_dir = wayland_protos.get_variable(pkgconfig: 'pkgdatadir') + +gen_client_header = generator( + wayland_scanner, + output: ['@[email protected]'], + arguments: ['-c', 'client-header', '@INPUT@', '@BUILD_DIR@/@[email protected]'], +) + +gen_private_code = generator( + wayland_scanner, + output: ['@[email protected]'], + arguments: ['-c', 'private-code', '@INPUT@', '@BUILD_DIR@/@[email protected]'], +) + +protocols = [ + join_paths(wl_protocol_dir, 'unstable/idle-inhibit/idle-inhibit-unstable-v1.xml') +] + +client_protocol_srcs = [] + +foreach protocol : protocols + client_header = gen_client_header.process(protocol) + code = gen_private_code.process(protocol) + client_protocol_srcs += [client_header, code] +endforeach + sources = [ config, 'widget/box.vala', @@ -47,13 +78,16 @@ sources = [ 'process.vala', 'time.vala', 'variable.vala', -] + 'idle-inhibit.h', + 'idle-inhibit.c', +] + client_protocol_srcs if get_option('lib') lib = library( meson.project_name(), sources, dependencies: deps, + vala_args: ['--pkg', 'AstalInhibitManager'], vala_header: meson.project_name() + '.h', vala_vapi: meson.project_name() + '-' + api_version + '.vapi', vala_gir: gir, @@ -92,6 +126,7 @@ if get_option('cli') executable( meson.project_name(), ['cli.vala', sources], + vala_args: ['--pkg', 'AstalInhibitManager'], dependencies: deps, install: true, ) diff --git a/core/src/widget/window.vala b/core/src/widget/window.vala index 17dc76d..73a4f5d 100644 --- a/core/src/widget/window.vala +++ b/core/src/widget/window.vala @@ -38,6 +38,9 @@ public class Window : Gtk.Window { return false; } + private InhibitManager? inhibit_manager; + private Inhibitor? inhibitor; + construct { if (check("initialize layer shell")) return; @@ -45,6 +48,24 @@ public class Window : Gtk.Window { height_request = 1; width_request = 1; init_for_window(this); + inhibit_manager = InhibitManager.get_default(); + } + + public bool inhibit { + set { + if(inhibit_manager == null) { + return; + } + if(value && inhibitor == null) { + inhibitor = inhibit_manager.inhibit(this); + } + else if(!value && inhibitor != null){ + inhibitor = null; + } + } + get { + return inhibitor != null; + } } public string namespace { diff --git a/core/vapi/AstalInhibitManager.vapi b/core/vapi/AstalInhibitManager.vapi new file mode 100644 index 0000000..33a6304 --- /dev/null +++ b/core/vapi/AstalInhibitManager.vapi @@ -0,0 +1,13 @@ +[CCode (cprefix = "Astal", gir_namespace = "Astal", lower_case_cprefix = "astal_")] +namespace Astal { + [CCode (cheader_filename = "idle-inhibit.h", type_id = "astal_idle_inhibit_manager_get_type()")] + public class InhibitManager : GLib.Object { + public static unowned InhibitManager? get_default(); + public Inhibitor inhibit (Gtk.Window window); + } + [CCode (cheader_filename = "idle-inhibit.h", free_function = "astal_inhibitor_free")] + [Compact] + public class Inhibitor { + } + +} |