summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorkotontrion <[email protected]>2024-09-24 10:47:14 +0200
committerkotontrion <[email protected]>2024-09-24 10:47:14 +0200
commit122112c320e62e52b3f0acc5d03c445c44bd8c4c (patch)
tree5fd80f779b938e767595f5ad37ecf87e7799a717 /core
parentba7d92df104f374a3796c0c95f3a9cda04976f6a (diff)
core: add window inhibit property
Diffstat (limited to 'core')
-rw-r--r--core/meson.build2
-rw-r--r--core/src/idle-inhibit.c124
-rw-r--r--core/src/idle-inhibit.h22
-rw-r--r--core/src/meson.build37
-rw-r--r--core/src/widget/window.vala21
-rw-r--r--core/vapi/AstalInhibitManager.vapi13
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, &registry_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 {
+ }
+
+}