[Xfce4-commits] [apps/xfdashboard] 03/19: Added GDK (for X11) window tracker backend
noreply at xfce.org
noreply at xfce.org
Fri Jun 16 10:56:34 CEST 2017
This is an automated email from the git hooks/post-receive script.
n o m a d p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository apps/xfdashboard.
commit 2adf25ead816b302001360ce541a9f5f26add783
Author: Stephan Haller <nomad at froevel.de>
Date: Tue Jun 13 07:37:54 2017 +0200
Added GDK (for X11) window tracker backend
Enhancement for issue GH #129
---
libxfdashboard/Makefile.am | 2 +
libxfdashboard/gdk/window-tracker-backend-gdk.c | 659 ++++++++++++++++++++++++
libxfdashboard/gdk/window-tracker-backend-gdk.h | 74 +++
3 files changed, 735 insertions(+)
diff --git a/libxfdashboard/Makefile.am b/libxfdashboard/Makefile.am
index bc1097e..3c6197d 100644
--- a/libxfdashboard/Makefile.am
+++ b/libxfdashboard/Makefile.am
@@ -253,6 +253,7 @@ endif
gdk_headers = \
gdk/window-content-gdk.h \
gdk/window-tracker-gdk.h \
+ gdk/window-tracker-backend-gdk.h \
gdk/window-tracker-monitor-gdk.h \
gdk/window-tracker-window-gdk.h \
gdk/window-tracker-workspace-gdk.h
@@ -260,6 +261,7 @@ gdk_headers = \
gdk_sources = \
gdk/window-content-gdk.c \
gdk/window-tracker-gdk.c \
+ gdk/window-tracker-backend-gdk.c \
gdk/window-tracker-monitor-gdk.c \
gdk/window-tracker-window-gdk.c \
gdk/window-tracker-workspace-gdk.c
diff --git a/libxfdashboard/gdk/window-tracker-backend-gdk.c b/libxfdashboard/gdk/window-tracker-backend-gdk.c
new file mode 100644
index 0000000..debf321
--- /dev/null
+++ b/libxfdashboard/gdk/window-tracker-backend-gdk.c
@@ -0,0 +1,659 @@
+/*
+ * window-tracker-backend: Window tracker backend providing special functions
+ * for different windowing and clutter backends.
+ *
+ * Copyright 2012-2016 Stephan Haller <nomad at froevel.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libxfdashboard/gdk/window-tracker-backend-gdk.h>
+
+#include <glib/gi18n-lib.h>
+#include <clutter/gdk/clutter-gdk.h>
+#include <clutter/x11/clutter-x11.h>
+#include <gdk/gdkx.h>
+#ifdef HAVE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#include <libxfdashboard/x11/window-tracker-x11.h>
+#include <libxfdashboard/x11/window-tracker-window-x11.h>
+#include <libxfdashboard/marshal.h>
+#include <libxfdashboard/compat.h>
+#include <libxfdashboard/debug.h>
+
+
+/* Define this class in GObject system */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_iface_init(XfdashboardWindowTrackerBackendInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowTrackerBackendGDK,
+ xfdashboard_window_tracker_backend_gdk,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND, _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_iface_init))
+
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDKPrivate))
+
+struct _XfdashboardWindowTrackerBackendGDKPrivate
+{
+ /* Instance related */
+ XfdashboardWindowTrackerX11 *windowTracker;
+};
+
+
+/* IMPLEMENTATION: Private variables and methods */
+
+/* State of stage window changed */
+static void _xfdashboard_window_tracker_backend_gdk_on_stage_state_changed(WnckWindow *inWindow,
+ WnckWindowState inChangedMask,
+ WnckWindowState inNewValue,
+ gpointer inUserData)
+{
+ XfdashboardWindowTrackerWindowX11 *stageWindow;
+
+ g_return_if_fail(WNCK_IS_WINDOW(inWindow));
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+ stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+ /* Set 'skip-tasklist' if changed */
+ if((inChangedMask & WNCK_WINDOW_STATE_SKIP_TASKLIST) &&
+ !(inNewValue & WNCK_WINDOW_STATE_SKIP_TASKLIST))
+ {
+ wnck_window_set_skip_tasklist(WNCK_WINDOW(inWindow), TRUE);
+ XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+ "State 'skip-tasklist' for stage window %p (wnck-window=%p) needs reset",
+ stageWindow,
+ inWindow);
+ }
+
+ /* Set 'skip-pager' if changed */
+ if((inChangedMask & WNCK_WINDOW_STATE_SKIP_PAGER) &&
+ !(inNewValue & WNCK_WINDOW_STATE_SKIP_PAGER))
+ {
+ wnck_window_set_skip_pager(WNCK_WINDOW(inWindow), TRUE);
+ XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+ "State 'skip-pager' for stage window %p (wnck-window=%p) needs reset",
+ stageWindow,
+ inWindow);
+ }
+
+ /* Set 'make-above' if changed */
+ if((inChangedMask & WNCK_WINDOW_STATE_ABOVE) &&
+ !(inNewValue & WNCK_WINDOW_STATE_ABOVE))
+ {
+ wnck_window_make_above(WNCK_WINDOW(inWindow));
+ XFDASHBOARD_DEBUG(inWindow, WINDOWS,
+ "State 'make-above' for stage window %p (wnck-window=%p) needs reset",
+ stageWindow,
+ inWindow);
+ }
+}
+
+/* The active window changed. Reselect stage window as active one if it is visible */
+static void _xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed(WnckScreen *inScreen,
+ WnckWindow *inPreviousWindow,
+ gpointer inUserData)
+{
+ XfdashboardWindowTrackerWindowX11 *stageWindow;
+ XfdashboardWindowTrackerWindowState stageWindowState;
+ WnckWindow *stageWnckWindow;
+ WnckWindow *activeWindow;
+ gboolean reselect;
+
+ g_return_if_fail(WNCK_IS_SCREEN(inScreen));
+ g_return_if_fail(inPreviousWindow==NULL || WNCK_IS_WINDOW(inPreviousWindow));
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+ stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+ reselect=FALSE;
+
+ /* Get wnck window of stage window */
+ stageWnckWindow=xfdashboard_window_tracker_window_x11_get_window(stageWindow);
+ if(!stageWnckWindow)
+ {
+ g_critical(_("Could not get real stage window to handle signal 'active-window-changed'"));
+ return;
+ }
+
+ /* Get stage of stage window */
+ stageWindowState=xfdashboard_window_tracker_window_get_state(XFDASHBOARD_WINDOW_TRACKER_WINDOW(stageWindow));
+
+ /* Reactive stage window if not hidden */
+ activeWindow=wnck_screen_get_active_window(inScreen);
+
+ if(inPreviousWindow && inPreviousWindow==stageWnckWindow) reselect=TRUE;
+ if(!activeWindow || activeWindow!=stageWnckWindow) reselect=TRUE;
+ if(!(stageWindowState & (XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED | XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_HIDDEN))) reselect=TRUE;
+
+ if(reselect)
+ {
+ wnck_window_activate_transient(stageWnckWindow, xfdashboard_window_tracker_x11_get_time());
+ XFDASHBOARD_DEBUG(stageWindow, WINDOWS,
+ "Active window changed from %p (%s) to %p (%s) but stage window %p (wnck-window=%p) is visible and should be active one",
+ inPreviousWindow, inPreviousWindow ? wnck_window_get_name(inPreviousWindow) : "<nil>",
+ activeWindow, activeWindow ? wnck_window_get_name(activeWindow) : "<nil>",
+ stageWindow,
+ stageWnckWindow);
+ }
+}
+
+/* Size of screen has changed so resize stage window */
+static void _xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed(XfdashboardWindowTracker *inWindowTracker,
+ gint inWidth,
+ gint inHeight,
+ gpointer inUserData)
+{
+#ifdef HAVE_XINERAMA
+ XfdashboardWindowTrackerWindowX11 *realStageWindow;
+ WnckWindow *stageWindow;
+ GdkDisplay *display;
+ GdkScreen *screen;
+ XineramaScreenInfo *monitors;
+ int monitorsCount;
+ gint top, bottom, left, right;
+ gint topIndex, bottomIndex, leftIndex, rightIndex;
+ gint i;
+ Atom atomFullscreenMonitors;
+ XEvent xEvent;
+
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(inWindowTracker));
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+ realStageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+ XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS, "Set fullscreen across all monitors using Xinerama");
+
+ /* Get wnck window for stage window object as it is needed a lot from this
+ * point on.
+ */
+ stageWindow=xfdashboard_window_tracker_window_x11_get_window(realStageWindow);
+
+ /* If window manager does not support fullscreen across all monitors
+ * return here.
+ */
+ if(!wnck_screen_net_wm_supports(wnck_window_get_screen(stageWindow), "_NET_WM_FULLSCREEN_MONITORS"))
+ {
+ g_warning(_("Keep window fullscreen on primary monitor because window manager does not support _NET_WM_FULLSCREEN_MONITORS."));
+ return;
+ }
+
+ /* Get display */
+ display=gdk_display_get_default();
+
+ /* Get screen */
+ screen=gdk_screen_get_default();
+
+ /* Check if Xinerama is active on display. If not try to move and resize
+ * stage window to primary monitor.
+ */
+ if(!XineramaIsActive(gdk_x11_display_get_xdisplay(display)))
+ {
+#if GTK_CHECK_VERSION(3, 22, 0)
+ GdkMonitor *primaryMonitor;
+#else
+ gint primaryMonitor;
+#endif
+ GdkRectangle geometry;
+
+ /* Get position and size of primary monitor and try to move and resize
+ * stage window to its position and size. Even if it fails it should
+ * resize the stage to the size of current monitor this window is
+ * fullscreened to. Tested with xfwm4.
+ */
+#if GTK_CHECK_VERSION(3, 22, 0)
+ primaryMonitor=gdk_display_get_primary_monitor(gdk_screen_get_display(screen));
+ gdk_monitor_get_geometry(primaryMonitor, &geometry);
+#else
+ primaryMonitor=gdk_screen_get_primary_monitor(screen);
+ gdk_screen_get_monitor_geometry(screen, primaryMonitor, &geometry);
+#endif
+ wnck_window_set_geometry(stageWindow,
+ WNCK_WINDOW_GRAVITY_STATIC,
+ WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y | WNCK_WINDOW_CHANGE_WIDTH | WNCK_WINDOW_CHANGE_HEIGHT,
+ geometry.x, geometry.y, geometry.width, geometry.height);
+ return;
+ }
+
+ /* Get monitors from Xinerama */
+ monitors=XineramaQueryScreens(GDK_DISPLAY_XDISPLAY(display), &monitorsCount);
+ if(monitorsCount<=0 || !monitors)
+ {
+ if(monitors) XFree(monitors);
+ return;
+ }
+
+ /* Get monitor indices for each corner of screen */
+ xfdashboard_window_tracker_get_screen_size(inWindowTracker, &left, &top);
+ bottom=0;
+ right=0;
+ topIndex=bottomIndex=leftIndex=rightIndex=0;
+ for(i=0; i<monitorsCount; i++)
+ {
+ XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+ "Checking edges at monitor %d with upper-left at %d,%d and lower-right at %d,%d [size: %dx%d]",
+ i,
+ monitors[i].x_org,
+ monitors[i].y_org,
+ monitors[i].x_org+monitors[i].width, monitors[i].y_org+monitors[i].height,
+ monitors[i].width, monitors[i].height);
+
+ if(left>monitors[i].x_org)
+ {
+ left=monitors[i].x_org;
+ leftIndex=i;
+ }
+
+ if(right<(monitors[i].x_org+monitors[i].width))
+ {
+ right=(monitors[i].x_org+monitors[i].width);
+ rightIndex=i;
+ }
+
+ if(top>monitors[i].y_org)
+ {
+ top=monitors[i].y_org;
+ topIndex=i;
+ }
+
+ if(bottom<(monitors[i].y_org+monitors[i].height))
+ {
+ bottom=(monitors[i].y_org+monitors[i].height);
+ bottomIndex=i;
+ }
+ }
+ XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+ "Found edge monitors: left=%d (monitor %d), right=%d (monitor %d), top=%d (monitor %d), bottom=%d (monitor %d)",
+ left, leftIndex,
+ right, rightIndex,
+ top, topIndex,
+ bottom, bottomIndex);
+
+ /* Get X atom for fullscreen-across-all-monitors */
+ atomFullscreenMonitors=XInternAtom(gdk_x11_display_get_xdisplay(display),
+ "_NET_WM_FULLSCREEN_MONITORS",
+ False);
+
+ /* Send event to X to set window to fullscreen over all monitors */
+ memset(&xEvent, 0, sizeof(xEvent));
+ xEvent.type=ClientMessage;
+ xEvent.xclient.window=wnck_window_get_xid(stageWindow);
+ xEvent.xclient.display=GDK_DISPLAY_XDISPLAY(display);
+ xEvent.xclient.message_type=atomFullscreenMonitors;
+ xEvent.xclient.format=32;
+ xEvent.xclient.data.l[0]=topIndex;
+ xEvent.xclient.data.l[1]=bottomIndex;
+ xEvent.xclient.data.l[2]=leftIndex;
+ xEvent.xclient.data.l[3]=rightIndex;
+ xEvent.xclient.data.l[4]=0;
+ XSendEvent(GDK_DISPLAY_XDISPLAY(display),
+ DefaultRootWindow(GDK_DISPLAY_XDISPLAY(display)),
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xEvent);
+
+ /* Release allocated resources */
+ if(monitors) XFree(monitors);
+#else
+ XfdashboardWindowTrackerWindowX11 *realStageWindow;
+ WnckWindow *stageWindow;
+ GdkScreen *screen;
+ gint primaryMonitor;
+ GdkRectangle geometry;
+
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER(inWindowTracker));
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inUserData));
+
+ realStageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inUserData);
+
+ XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS, "No support for multiple monitor: Setting fullscreen on primary monitor");
+
+ /* Get wnck window for stage window object as it is needed a lot from this
+ * point on.
+ */
+ stageWindow=xfdashboard_window_tracker_window_gdk_get_window(realStageWindow);
+
+ /* Get screen */
+ screen=gdk_screen_get_default();
+
+ /* Get position and size of primary monitor and try to move and resize
+ * stage window to its position and size. Even if it fails it should
+ * resize the stage to the size of current monitor this window is
+ * fullscreened to. Tested with xfwm4.
+ */
+ primaryMonitor=gdk_screen_get_primary_monitor(screen);
+ gdk_screen_get_monitor_geometry(screen, primaryMonitor, &geometry);
+ wnck_window_set_geometry(stageWindow,
+ WNCK_WINDOW_GRAVITY_STATIC,
+ WNCK_WINDOW_CHANGE_X | WNCK_WINDOW_CHANGE_Y | WNCK_WINDOW_CHANGE_WIDTH | WNCK_WINDOW_CHANGE_HEIGHT,
+ geometry.x, geometry.y, geometry.width, geometry.height);
+
+ XFDASHBOARD_DEBUG(inWindowTracker, WINDOWS,
+ "Moving stage window to %d,%d and resize to %dx%d",
+ geometry.x, geometry.y,
+ geometry.width, geometry.height);
+#endif
+}
+
+
+/* IMPLEMENTATION: XfdashboardWindowTrackerBackend */
+
+/* Get name of backend */
+static const gchar* _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_name(XfdashboardWindowTrackerBackend *inBackend)
+{
+ g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend), NULL);
+
+ /* Return name of backend */
+ return("GDK-X11");
+}
+
+/* Get window tracker instance used by this backend */
+static XfdashboardWindowTracker* _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_window_tracker(XfdashboardWindowTrackerBackend *inBackend)
+{
+ XfdashboardWindowTrackerBackendGDK *self;
+ XfdashboardWindowTrackerBackendGDKPrivate *priv;
+
+ g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend), NULL);
+
+ self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inBackend);
+ priv=self->priv;
+
+ /* Return window tracker instance used by this instance but do not take a
+ * reference on it as it will be done by the backend interface when
+ * xfdashboard_window_tracker_backend_get_default() is called.
+ */
+ return(XFDASHBOARD_WINDOW_TRACKER(priv->windowTracker));
+}
+
+/* Set up and show window for use as stage */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_show_stage_window(XfdashboardWindowTrackerBackend *inBackend,
+ XfdashboardWindowTrackerWindow *inStageWindow)
+{
+ XfdashboardWindowTrackerBackendGDK *self;
+ XfdashboardWindowTrackerBackendGDKPrivate *priv;
+ XfdashboardWindowTrackerWindowX11 *stageWindow;
+ GdkWindow *stageGdkWindow;
+ WnckWindow *stageWnckWindow;
+ WnckScreen *screen;
+ guint signalID;
+ gulong handlerID;
+ gint width, height;
+
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend));
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inStageWindow));
+
+ self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inBackend);
+ priv=self->priv;
+ stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inStageWindow);
+
+ /* Get GDK stage window */
+ stageGdkWindow=clutter_gdk_get_stage_window(xfdashboard_window_tracker_window_get_stage(inStageWindow));
+ if(!stageGdkWindow)
+ {
+ g_critical(_("Could not get real stage window to show"));
+ return;
+ }
+
+ /* Window of stage should always be above all other windows, pinned to all
+ * workspaces, not be listed in window pager and set to fullscreen
+ */
+ gdk_window_set_skip_taskbar_hint(stageGdkWindow, TRUE);
+ gdk_window_set_skip_pager_hint(stageGdkWindow, TRUE);
+ gdk_window_set_keep_above(stageGdkWindow, TRUE);
+ gdk_window_stick(stageGdkWindow);
+#if GTK_CHECK_VERSION(3, 8, 0)
+ gdk_window_set_fullscreen_mode(stageGdkWindow, GDK_FULLSCREEN_ON_ALL_MONITORS);
+#endif
+ gdk_window_fullscreen(stageGdkWindow);
+
+ /* Get wnck window and screen of window */
+ stageWnckWindow=wnck_window_get(gdk_x11_window_get_xid(stageGdkWindow));
+ screen=wnck_window_get_screen(stageWnckWindow);
+
+ /* Connect signals if not already connected */
+ signalID=g_signal_lookup("state-changed", WNCK_TYPE_WINDOW);
+ handlerID=g_signal_handler_find(stageWnckWindow,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ signalID,
+ 0,
+ NULL,
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_state_changed),
+ NULL);
+ if(!handlerID)
+ {
+ g_signal_connect(stageWnckWindow,
+ "state-changed",
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_state_changed),
+ stageWindow);
+ XFDASHBOARD_DEBUG(self, WINDOWS,
+ "Connecting signal to 'state-changed' at window %p (wnck-window=%p)",
+ stageWindow,
+ stageWnckWindow);
+ }
+
+ signalID=g_signal_lookup("active-window-changed", WNCK_TYPE_SCREEN);
+ handlerID=g_signal_handler_find(screen,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ signalID,
+ 0,
+ NULL,
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed),
+ NULL);
+ if(!handlerID)
+ {
+ g_signal_connect(screen,
+ "active-window-changed",
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed),
+ self);
+ XFDASHBOARD_DEBUG(self, WINDOWS,
+ "Connecting signal to 'active-window-changed' at screen %p of window %p (wnck-window=%p)",
+ screen,
+ stageWindow,
+ stageWnckWindow);
+ }
+
+ signalID=g_signal_lookup("screen-size-changed", XFDASHBOARD_TYPE_WINDOW_TRACKER);
+ handlerID=g_signal_handler_find(priv->windowTracker,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ signalID,
+ 0,
+ NULL,
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed),
+ NULL);
+ if(!handlerID)
+ {
+ g_signal_connect(priv->windowTracker,
+ "screen-size-changed",
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed),
+ self);
+ XFDASHBOARD_DEBUG(self, WINDOWS,
+ "Connecting signal to 'screen-size-changed' at window %p (wnck-window=%p)",
+ stageWindow,
+ stageWnckWindow);
+ }
+ xfdashboard_window_tracker_get_screen_size(XFDASHBOARD_WINDOW_TRACKER(priv->windowTracker), &width, &height);
+ _xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed(XFDASHBOARD_WINDOW_TRACKER(priv->windowTracker),
+ width,
+ height,
+ self);
+
+ /* Now the window is set up and we can show it */
+ xfdashboard_window_tracker_window_show(inStageWindow);
+}
+
+/* Unset up and hide stage window */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_hide_stage_window(XfdashboardWindowTrackerBackend *inBackend,
+ XfdashboardWindowTrackerWindow *inStageWindow)
+{
+ XfdashboardWindowTrackerBackendGDK *self;
+ XfdashboardWindowTrackerBackendGDKPrivate *priv;
+ XfdashboardWindowTrackerWindowX11 *stageWindow;
+ GdkWindow *stageGdkWindow;
+ WnckWindow *stageWnckWindow;
+ WnckScreen *screen;
+ guint signalID;
+ gulong handlerID;
+
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(inBackend));
+ g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inStageWindow));
+
+ self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inBackend);
+ priv=self->priv;
+ stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inStageWindow);
+
+ /* Get GDK stage window */
+ stageGdkWindow=clutter_gdk_get_stage_window(xfdashboard_window_tracker_window_get_stage(inStageWindow));
+ if(!stageGdkWindow)
+ {
+ g_critical(_("Could not get real stage window to show"));
+ return;
+ }
+
+ /* First hide window before removing signals etc. */
+ xfdashboard_window_tracker_window_hide(inStageWindow);
+
+ /* Get wnck window and screen of window */
+ stageWnckWindow=wnck_window_get(gdk_x11_window_get_xid(stageGdkWindow));
+ screen=wnck_window_get_screen(stageWnckWindow);
+
+ /* Disconnect signals */
+ signalID=g_signal_lookup("state-changed", WNCK_TYPE_WINDOW);
+ handlerID=g_signal_handler_find(stageWnckWindow,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ signalID,
+ 0,
+ NULL,
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_state_changed),
+ NULL);
+ if(handlerID)
+ {
+ g_signal_handler_disconnect(stageWnckWindow, handlerID);
+ XFDASHBOARD_DEBUG(self, WINDOWS,
+ "Disconnecting handler %lu for signal 'state-changed' at window %p (wnck-window=%p)",
+ handlerID,
+ stageWindow,
+ stageWnckWindow);
+ }
+
+ signalID=g_signal_lookup("active-window-changed", WNCK_TYPE_SCREEN);
+ handlerID=g_signal_handler_find(screen,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ signalID,
+ 0,
+ NULL,
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_active_window_changed),
+ NULL);
+ if(handlerID)
+ {
+ g_signal_handler_disconnect(screen, handlerID);
+ XFDASHBOARD_DEBUG(self, WINDOWS,
+ "Disconnecting handler %lu for signal 'active-window-changed' at screen %p of window %p (wnck-window=%p)",
+ handlerID,
+ screen,
+ stageWindow,
+ stageWnckWindow);
+ }
+
+ signalID=g_signal_lookup("screen-size-changed", XFDASHBOARD_TYPE_WINDOW_TRACKER);
+ handlerID=g_signal_handler_find(priv->windowTracker,
+ G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC,
+ signalID,
+ 0,
+ NULL,
+ G_CALLBACK(_xfdashboard_window_tracker_backend_gdk_on_stage_screen_size_changed),
+ NULL);
+ if(handlerID)
+ {
+ g_signal_handler_disconnect(priv->windowTracker, handlerID);
+ XFDASHBOARD_DEBUG(self, WINDOWS,
+ "Disconnecting handler %lu for signal 'screen-size-changed' at window %p (wnck-window=%p)",
+ handlerID,
+ stageWindow,
+ stageWnckWindow);
+ }
+}
+
+/* Interface initialization
+ * Set up default functions
+ */
+static void _xfdashboard_window_tracker_backend_gdk_window_tracker_backend_iface_init(XfdashboardWindowTrackerBackendInterface *iface)
+{
+ iface->get_name=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_name;
+
+ iface->get_window_tracker=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_get_window_tracker;
+
+ iface->show_stage_window=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_show_stage_window;
+ iface->hide_stage_window=_xfdashboard_window_tracker_backend_gdk_window_tracker_backend_hide_stage_window;
+}
+
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_tracker_backend_gdk_dispose(GObject *inObject)
+{
+ XfdashboardWindowTrackerBackendGDK *self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(inObject);
+ XfdashboardWindowTrackerBackendGDKPrivate *priv=self->priv;
+
+ /* Dispose allocated resources */
+ if(priv->windowTracker)
+ {
+ g_object_unref(priv->windowTracker);
+ priv->windowTracker=NULL;
+ }
+
+ /* Call parent's class dispose method */
+ G_OBJECT_CLASS(xfdashboard_window_tracker_backend_gdk_parent_class)->dispose(inObject);
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+void xfdashboard_window_tracker_backend_gdk_class_init(XfdashboardWindowTrackerBackendGDKClass *klass)
+{
+ GObjectClass *gobjectClass=G_OBJECT_CLASS(klass);
+
+ /* Override functions */
+ gobjectClass->dispose=_xfdashboard_window_tracker_backend_gdk_dispose;
+
+ /* Set up private structure */
+ g_type_class_add_private(klass, sizeof(XfdashboardWindowTrackerBackendGDKPrivate));
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+void xfdashboard_window_tracker_backend_gdk_init(XfdashboardWindowTrackerBackendGDK *self)
+{
+ XfdashboardWindowTrackerBackendGDKPrivate *priv;
+
+ priv=self->priv=XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_GET_PRIVATE(self);
+
+ XFDASHBOARD_DEBUG(self, WINDOWS, "Initializing GDK-X11 window tracker backend");
+
+ /* Create window tracker instance */
+ priv->windowTracker=g_object_new(XFDASHBOARD_TYPE_WINDOW_TRACKER_X11, NULL);
+}
diff --git a/libxfdashboard/gdk/window-tracker-backend-gdk.h b/libxfdashboard/gdk/window-tracker-backend-gdk.h
new file mode 100644
index 0000000..77b81f1
--- /dev/null
+++ b/libxfdashboard/gdk/window-tracker-backend-gdk.h
@@ -0,0 +1,74 @@
+/*
+ * window-tracker-backend: Window tracker backend providing special functions
+ * for different windowing and clutter backends.
+ *
+ * Copyright 2012-2017 Stephan Haller <nomad at froevel.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+#ifndef __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK__
+#define __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && !defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+#include <libxfdashboard/window-tracker-backend.h>
+
+G_BEGIN_DECLS
+
+#define XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK (xfdashboard_window_tracker_backend_gdk_get_type())
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDK))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK))
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDKClass))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_GDK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK))
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_GDK, XfdashboardWindowTrackerBackendGDKClass))
+
+typedef struct _XfdashboardWindowTrackerBackendGDK XfdashboardWindowTrackerBackendGDK;
+typedef struct _XfdashboardWindowTrackerBackendGDKClass XfdashboardWindowTrackerBackendGDKClass;
+typedef struct _XfdashboardWindowTrackerBackendGDKPrivate XfdashboardWindowTrackerBackendGDKPrivate;
+
+struct _XfdashboardWindowTrackerBackendGDK
+{
+ /*< private >*/
+ /* Parent instance */
+ GObject parent_instance;
+
+ /* Private structure */
+ XfdashboardWindowTrackerBackendGDKPrivate *priv;
+};
+
+struct _XfdashboardWindowTrackerBackendGDKClass
+{
+ /*< private >*/
+ /* Parent class */
+ GObjectClass parent_class;
+
+ /*< public >*/
+ /* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_window_tracker_backend_gdk_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_GDK__ */
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list