summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk/wayland/gdkdisplay-wayland.c6
-rw-r--r--gdk/wayland/gdkdisplay-wayland.h2
-rw-r--r--gdk/wayland/gdksurface-wayland.c36
-rw-r--r--gdk/wayland/gdkwaylandsurface.h3
-rw-r--r--gdk/wayland/meson.build1
-rw-r--r--gtk/gtkapplication-wayland.c104
-rw-r--r--gtk/gtkshortcutssection.c10
7 files changed, 155 insertions, 7 deletions
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index af30f9cfc2..45f937dfab 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -544,6 +544,12 @@ gdk_registry_handle_global (void *data,
gdk_wayland_display_init_xdg_output (display_wayland);
_gdk_wayland_display_async_roundtrip (display_wayland);
}
+ else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0)
+ {
+ display_wayland->idle_inhibit_manager =
+ wl_registry_bind (display_wayland->wl_registry, id,
+ &zwp_idle_inhibit_manager_v1_interface, 1);
+ }
g_hash_table_insert (display_wayland->known_globals,
GUINT_TO_POINTER (id), g_strdup (interface));
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index 5ace0f2744..db5e6a4fb3 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -35,6 +35,7 @@
#include <gdk/wayland/keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h>
#include <gdk/wayland/server-decoration-client-protocol.h>
#include <gdk/wayland/xdg-output-unstable-v1-client-protocol.h>
+#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
#include <glib.h>
#include <gdk/gdkkeys.h>
@@ -109,6 +110,7 @@ struct _GdkWaylandDisplay
struct zwp_keyboard_shortcuts_inhibit_manager_v1 *keyboard_shortcuts_inhibit;
struct org_kde_kwin_server_decoration_manager *server_decoration_manager;
struct zxdg_output_manager_v1 *xdg_output_manager;
+ struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
GList *async_roundtrips;
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index ef3f277664..46fec90c8e 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -191,6 +191,9 @@ struct _GdkWaylandSurface
struct zxdg_imported_v1 *imported_transient_for;
GHashTable *shortcuts_inhibitors;
+
+ struct zwp_idle_inhibitor_v1 *idle_inhibitor;
+ size_t idle_inhibitor_refcount;
};
struct _GdkWaylandSurfaceClass
@@ -1984,6 +1987,39 @@ gdk_wayland_surface_announce_csd (GdkSurface *surface)
ORG_KDE_KWIN_SERVER_DECORATION_MANAGER_MODE_CLIENT);
}
+gboolean
+gdk_wayland_surface_inhibit_idle (GdkSurface *surface)
+{
+ GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+
+ if (!display_wayland->idle_inhibit_manager)
+ return false;
+ if (!impl->idle_inhibitor)
+ {
+ g_assert (impl->idle_inhibitor_refcount == 0);
+ impl->idle_inhibitor =
+ zwp_idle_inhibit_manager_v1_create_inhibitor (display_wayland->idle_inhibit_manager,
+ impl->display_server.wl_surface);
+ }
+ ++impl->idle_inhibitor_refcount;
+ return true;
+}
+
+void
+gdk_wayland_surface_uninhibit_idle (GdkSurface *surface)
+{
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+
+ g_assert (impl->idle_inhibitor && impl->idle_inhibitor_refcount > 0);
+
+ if (--impl->idle_inhibitor_refcount == 0)
+ {
+ zwp_idle_inhibitor_v1_destroy (impl->idle_inhibitor);
+ impl->idle_inhibitor = NULL;
+ }
+}
+
static void
calculate_popup_rect (GdkSurface *surface,
GdkPopupLayout *layout,
diff --git a/gdk/wayland/gdkwaylandsurface.h b/gdk/wayland/gdkwaylandsurface.h
index 4af358c33e..54e0c6ff49 100644
--- a/gdk/wayland/gdkwaylandsurface.h
+++ b/gdk/wayland/gdkwaylandsurface.h
@@ -80,6 +80,9 @@ void gdk_wayland_surface_set_application_id (GdkSurface *sur
void gdk_wayland_surface_announce_csd (GdkSurface *surface);
+gboolean gdk_wayland_surface_inhibit_idle (GdkSurface *surface);
+void gdk_wayland_surface_uninhibit_idle (GdkSurface *surface);
+
G_END_DECLS
#endif /* __GDK_WAYLAND_SURFACE_H__ */
diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build
index 14267f4ccc..67ebb63da5 100644
--- a/gdk/wayland/meson.build
+++ b/gdk/wayland/meson.build
@@ -54,6 +54,7 @@ proto_sources = [
['keyboard-shortcuts-inhibit', 'unstable', 'v1', ],
['server-decoration', 'private' ],
['xdg-output', 'unstable', 'v1', ],
+ ['idle-inhibit', 'unstable', 'v1', ],
]
gdk_wayland_gen_headers = []
diff --git a/gtk/gtkapplication-wayland.c b/gtk/gtkapplication-wayland.c
index 34d85e31bb..face15505c 100644
--- a/gtk/gtkapplication-wayland.c
+++ b/gtk/gtkapplication-wayland.c
@@ -1,6 +1,7 @@
/*
* Copyright © 2010 Codethink Limited
* Copyright © 2013 Canonical Limited
+ * Copyright © 2020 Emmanuel Gil Peyrot
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,12 +25,42 @@
#include "gtknative.h"
#include <gdk/wayland/gdkwayland.h>
+#include <gdk/wayland/gdkdisplay-wayland.h>
+#include <gdk/wayland/idle-inhibit-unstable-v1-client-protocol.h>
-typedef GtkApplicationImplDBusClass GtkApplicationImplWaylandClass;
+typedef struct
+{
+ GtkApplicationImplDBusClass parent_class;
+
+ /* stores the dbus version of the overriden methods */
+ guint (*dbus_inhibit) (GtkApplicationImpl *impl,
+ GtkWindow *window,
+ GtkApplicationInhibitFlags flags,
+ const gchar *reason);
+ void (*dbus_uninhibit) (GtkApplicationImpl *impl,
+ guint cookie);
+} GtkApplicationImplWaylandClass;
+
+typedef struct
+{
+ guint cookie;
+ guint dbus_cookie;
+ GtkApplicationInhibitFlags flags;
+ GdkSurface *surface;
+
+} GtkApplicationWaylandInhibitor;
+
+static void
+gtk_application_wayland_inhibitor_free (GtkApplicationWaylandInhibitor *inhibitor)
+{
+ g_slice_free (GtkApplicationWaylandInhibitor, inhibitor);
+}
typedef struct
{
GtkApplicationImplDBus dbus;
+ GSList *inhibitors;
+ guint next_cookie;
} GtkApplicationImplWayland;
@@ -72,6 +103,70 @@ gtk_application_impl_wayland_before_emit (GtkApplicationImpl *impl,
gdk_wayland_display_set_startup_notification_id (gdk_display_get_default (), startup_notification_id);
}
+static guint
+gtk_application_impl_wayland_inhibit (GtkApplicationImpl *impl,
+ GtkWindow *window,
+ GtkApplicationInhibitFlags flags,
+ const gchar *reason)
+{
+ GtkApplicationImplWayland *wayland = (GtkApplicationImplWayland *) impl;
+ GdkSurface *surface;
+ GtkApplicationWaylandInhibitor *inhibitor;
+ gboolean success;
+
+ if (!flags)
+ return 0;
+
+ inhibitor = g_slice_new (GtkApplicationWaylandInhibitor);
+ inhibitor->cookie = ++wayland->next_cookie;
+ inhibitor->flags = flags;
+ wayland->inhibitors = g_slist_prepend (wayland->inhibitors, inhibitor);
+
+ if (flags & GTK_APPLICATION_INHIBIT_IDLE)
+ {
+ surface = gtk_native_get_surface (GTK_NATIVE (window));
+ if (GDK_IS_WAYLAND_SURFACE (surface))
+ {
+ success = gdk_wayland_surface_inhibit_idle (surface);
+ if (success)
+ {
+ flags &= ~GTK_APPLICATION_INHIBIT_IDLE;
+ inhibitor->surface = surface;
+ }
+ }
+ }
+
+ inhibitor->dbus_cookie = ((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_inhibit (impl, window, flags, reason);
+
+ return inhibitor->cookie;
+}
+
+static void
+gtk_application_impl_wayland_uninhibit (GtkApplicationImpl *impl,
+ guint cookie)
+{
+ GtkApplicationImplWayland *wayland = (GtkApplicationImplWayland *) impl;
+ GSList *iter;
+
+ for (iter = wayland->inhibitors; iter; iter = iter->next)
+ {
+ GtkApplicationWaylandInhibitor *inhibitor = iter->data;
+
+ if (inhibitor->cookie == cookie)
+ {
+ if (inhibitor->dbus_cookie)
+ ((GtkApplicationImplWaylandClass *) G_OBJECT_GET_CLASS (wayland))->dbus_uninhibit (impl, inhibitor->dbus_cookie);
+ if (inhibitor->surface)
+ gdk_wayland_surface_uninhibit_idle (inhibitor->surface);
+ gtk_application_wayland_inhibitor_free (inhibitor);
+ wayland->inhibitors = g_slist_delete_link (wayland->inhibitors, iter);
+ return;
+ }
+ }
+
+ g_warning ("Invalid inhibitor cookie");
+}
+
static void
gtk_application_impl_wayland_init (GtkApplicationImplWayland *wayland)
{
@@ -82,8 +177,15 @@ gtk_application_impl_wayland_class_init (GtkApplicationImplWaylandClass *class)
{
GtkApplicationImplClass *impl_class = GTK_APPLICATION_IMPL_CLASS (class);
+ class->dbus_inhibit = impl_class->inhibit;
+ class->dbus_uninhibit = impl_class->uninhibit;
+
impl_class->handle_window_realize =
gtk_application_impl_wayland_handle_window_realize;
impl_class->before_emit =
gtk_application_impl_wayland_before_emit;
+ impl_class->inhibit =
+ gtk_application_impl_wayland_inhibit;
+ impl_class->uninhibit =
+ gtk_application_impl_wayland_uninhibit;
}
diff --git a/gtk/gtkshortcutssection.c b/gtk/gtkshortcutssection.c
index 7aef6791f5..5f5be70582 100644
--- a/gtk/gtkshortcutssection.c
+++ b/gtk/gtkshortcutssection.c
@@ -543,21 +543,20 @@ gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self)
{
GtkWidget *column;
- for (column = gtk_widget_get_first_child (page);
+ for (column = gtk_widget_get_last_child (page);
column != NULL;
- column = gtk_widget_get_next_sibling (column))
+ column = gtk_widget_get_prev_sibling (column))
{
GtkWidget *group;
- for (group = gtk_widget_get_first_child (column);
+ for (group = gtk_widget_get_last_child (column);
group != NULL;
- group = gtk_widget_get_next_sibling (group))
+ group = gtk_widget_get_prev_sibling (group))
{
groups = g_list_prepend (groups, group);
}
}
}
- groups = g_list_reverse (groups);
/* create new pages */
current_page = NULL;
@@ -642,7 +641,6 @@ gtk_shortcuts_section_reflow_groups (GtkShortcutsSection *self)
child != NULL;
child = gtk_widget_get_prev_sibling (child))
content = g_list_prepend (content, child);
- content = g_list_reverse (content);
n = 0;
for (g = g_list_last (content); g; g = g->prev)