[Xfce4-commits] [apps/xfdashboard] 02/19: Added X11 window tracker backend

noreply at xfce.org noreply at xfce.org
Fri Jun 16 10:56:33 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 02c921a6a87ed7cc46e35fa12c008c5fb7f31384
Author: Stephan Haller <nomad at froevel.de>
Date:   Tue Jun 13 07:36:41 2017 +0200

    Added X11 window tracker backend
    
    Enhancement for issue GH #129
---
 libxfdashboard/Makefile.am                      |   2 +
 libxfdashboard/x11/window-tracker-backend-x11.c | 650 ++++++++++++++++++++++++
 libxfdashboard/x11/window-tracker-backend-x11.h |  74 +++
 3 files changed, 726 insertions(+)

diff --git a/libxfdashboard/Makefile.am b/libxfdashboard/Makefile.am
index d8ec8da..bc1097e 100644
--- a/libxfdashboard/Makefile.am
+++ b/libxfdashboard/Makefile.am
@@ -210,6 +210,7 @@ libxfdashboard_la_LDFLAGS = \
 x11_headers = \
 	x11/window-content-x11.h \
 	x11/window-tracker-x11.h \
+	x11/window-tracker-backend-x11.h \
 	x11/window-tracker-monitor-x11.h \
 	x11/window-tracker-window-x11.h \
 	x11/window-tracker-workspace-x11.h
@@ -217,6 +218,7 @@ x11_headers = \
 x11_sources = \
 	x11/window-content-x11.c \
 	x11/window-tracker-x11.c \
+	x11/window-tracker-backend-x11.c \
 	x11/window-tracker-monitor-x11.c \
 	x11/window-tracker-window-x11.c \
 	x11/window-tracker-workspace-x11.c
diff --git a/libxfdashboard/x11/window-tracker-backend-x11.c b/libxfdashboard/x11/window-tracker-backend-x11.c
new file mode 100644
index 0000000..02c5945
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-backend-x11.c
@@ -0,0 +1,650 @@
+/*
+ * 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/x11/window-tracker-backend-x11.h>
+
+#include <glib/gi18n-lib.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_x11_window_tracker_backend_iface_init(XfdashboardWindowTrackerBackendInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(XfdashboardWindowTrackerBackendX11,
+						xfdashboard_window_tracker_backend_x11,
+						G_TYPE_OBJECT,
+						G_IMPLEMENT_INTERFACE(XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND, _xfdashboard_window_tracker_backend_x11_window_tracker_backend_iface_init))
+
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_X11, XfdashboardWindowTrackerBackendX11Private))
+
+struct _XfdashboardWindowTrackerBackendX11Private
+{
+	/* Instance related */
+	XfdashboardWindowTrackerX11		*windowTracker;
+};
+
+
+/* IMPLEMENTATION: Private variables and methods */
+
+/* State of stage window changed */
+static void _xfdashboard_window_tracker_backend_x11_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_x11_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_x11_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_x11_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_x11_window_tracker_backend_get_name(XfdashboardWindowTrackerBackend *inBackend)
+{
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_X11(inBackend), NULL);
+
+	/* Return name of backend */
+	return("X11");
+}
+
+/* Get window tracker instance used by this backend */
+static XfdashboardWindowTracker* _xfdashboard_window_tracker_backend_x11_window_tracker_backend_get_window_tracker(XfdashboardWindowTrackerBackend *inBackend)
+{
+	XfdashboardWindowTrackerBackendX11				*self;
+	XfdashboardWindowTrackerBackendX11Private		*priv;
+
+	g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_X11(inBackend), NULL);
+
+	self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11(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_x11_window_tracker_backend_show_stage_window(XfdashboardWindowTrackerBackend *inBackend,
+																								XfdashboardWindowTrackerWindow *inStageWindow)
+{
+	XfdashboardWindowTrackerBackendX11			*self;
+	XfdashboardWindowTrackerBackendX11Private	*priv;
+	XfdashboardWindowTrackerWindowX11			*stageWindow;
+	WnckWindow									*stageWnckWindow;
+	WnckScreen									*screen;
+	guint										signalID;
+	gulong										handlerID;
+	gint										width, height;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_X11(inBackend));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inStageWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11(inBackend);
+	priv=self->priv;
+	stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inStageWindow);
+
+	/* 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 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
+	 */
+	if(!wnck_window_is_skip_tasklist(stageWnckWindow)) wnck_window_set_skip_tasklist(stageWnckWindow, TRUE);
+	if(!wnck_window_is_skip_pager(stageWnckWindow)) wnck_window_set_skip_pager(stageWnckWindow, TRUE);
+	if(!wnck_window_is_above(stageWnckWindow)) wnck_window_make_above(stageWnckWindow);
+	if(!wnck_window_is_pinned(stageWnckWindow)) wnck_window_pin(stageWnckWindow);
+
+	/* Get screen of window */
+	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_x11_on_stage_state_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(stageWnckWindow,
+							"state-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_backend_x11_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_x11_on_stage_active_window_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(screen,
+							"active-window-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_backend_x11_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_x11_on_stage_screen_size_changed),
+									NULL);
+	if(!handlerID)
+	{
+		g_signal_connect(priv->windowTracker,
+							"screen-size-changed",
+							G_CALLBACK(_xfdashboard_window_tracker_backend_x11_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_x11_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_x11_window_tracker_backend_hide_stage_window(XfdashboardWindowTrackerBackend *inBackend,
+																								XfdashboardWindowTrackerWindow *inStageWindow)
+{
+	XfdashboardWindowTrackerBackendX11			*self;
+	XfdashboardWindowTrackerBackendX11Private	*priv;
+	XfdashboardWindowTrackerWindowX11			*stageWindow;
+	WnckWindow									*stageWnckWindow;
+	WnckScreen									*screen;
+	guint										signalID;
+	gulong										handlerID;
+
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_X11(inBackend));
+	g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW_X11(inStageWindow));
+
+	self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11(inBackend);
+	priv=self->priv;
+	stageWindow=XFDASHBOARD_WINDOW_TRACKER_WINDOW_X11(inStageWindow);
+
+	/* 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 hide"));
+		return;
+	}
+
+	/* First hide window before removing signals etc. */
+	xfdashboard_window_tracker_window_hide(inStageWindow);
+
+	/* Get screen of window */
+	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_x11_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_x11_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_x11_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_x11_window_tracker_backend_iface_init(XfdashboardWindowTrackerBackendInterface *iface)
+{
+	iface->get_name=_xfdashboard_window_tracker_backend_x11_window_tracker_backend_get_name;
+
+	iface->get_window_tracker=_xfdashboard_window_tracker_backend_x11_window_tracker_backend_get_window_tracker;
+
+	iface->show_stage_window=_xfdashboard_window_tracker_backend_x11_window_tracker_backend_show_stage_window;
+	iface->hide_stage_window=_xfdashboard_window_tracker_backend_x11_window_tracker_backend_hide_stage_window;
+}
+
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object */
+static void _xfdashboard_window_tracker_backend_x11_dispose(GObject *inObject)
+{
+	XfdashboardWindowTrackerBackendX11				*self=XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11(inObject);
+	XfdashboardWindowTrackerBackendX11Private		*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_x11_parent_class)->dispose(inObject);
+}
+
+/* Class initialization
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+void xfdashboard_window_tracker_backend_x11_class_init(XfdashboardWindowTrackerBackendX11Class *klass)
+{
+	GObjectClass						*gobjectClass=G_OBJECT_CLASS(klass);
+
+	/* Override functions */
+	gobjectClass->dispose=_xfdashboard_window_tracker_backend_x11_dispose;
+
+	/* Set up private structure */
+	g_type_class_add_private(klass, sizeof(XfdashboardWindowTrackerBackendX11Private));
+}
+
+/* Object initialization
+ * Create private structure and set up default values
+ */
+void xfdashboard_window_tracker_backend_x11_init(XfdashboardWindowTrackerBackendX11 *self)
+{
+	XfdashboardWindowTrackerBackendX11Private		*priv;
+
+	priv=self->priv=XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11_GET_PRIVATE(self);
+
+	XFDASHBOARD_DEBUG(self, WINDOWS, "Initializing X11 window tracker backend");
+
+	/* Create window tracker instance */
+	priv->windowTracker=g_object_new(XFDASHBOARD_TYPE_WINDOW_TRACKER_X11, NULL);
+}
diff --git a/libxfdashboard/x11/window-tracker-backend-x11.h b/libxfdashboard/x11/window-tracker-backend-x11.h
new file mode 100644
index 0000000..b96a49b
--- /dev/null
+++ b/libxfdashboard/x11/window-tracker-backend-x11.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_X11__
+#define __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_X11__
+
+#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_X11				(xfdashboard_window_tracker_backend_x11_get_type())
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_X11, XfdashboardWindowTrackerBackendX11))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_X11(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_X11, XfdashboardWindowTrackerBackendX11Class))
+#define XFDASHBOARD_IS_WINDOW_TRACKER_BACKEND_X11_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_X11))
+#define XFDASHBOARD_WINDOW_TRACKER_BACKEND_X11_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_WINDOW_TRACKER_BACKEND_X11, XfdashboardWindowTrackerBackendX11Class))
+
+typedef struct _XfdashboardWindowTrackerBackendX11				XfdashboardWindowTrackerBackendX11;
+typedef struct _XfdashboardWindowTrackerBackendX11Class			XfdashboardWindowTrackerBackendX11Class;
+typedef struct _XfdashboardWindowTrackerBackendX11Private		XfdashboardWindowTrackerBackendX11Private;
+
+struct _XfdashboardWindowTrackerBackendX11
+{
+	/*< private >*/
+	/* Parent instance */
+	GObject											parent_instance;
+
+	/* Private structure */
+	XfdashboardWindowTrackerBackendX11Private		*priv;
+};
+
+struct _XfdashboardWindowTrackerBackendX11Class
+{
+	/*< private >*/
+	/* Parent class */
+	GObjectClass									parent_class;
+
+	/*< public >*/
+	/* Virtual functions */
+};
+
+/* Public API */
+GType xfdashboard_window_tracker_backend_x11_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif	/* __LIBXFDASHBOARD_WINDOW_TRACKER_BACKEND_X11__ */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list