[patch] Forward scroll and unused button events to the window manager

Brian J. Tarricone bjt23 at cornell.edu
Sun Sep 26 00:25:38 CEST 2004


patch committed, with a few style changes and a fix for multihead 
setups.  thanks!

    -brian

Nils Rennebarth wrote:

> Hi,
>
> I implemented Olivers advice to make xfdesktop forward scrolls and 
> unused button presses/releases that have been caught by its virtual 
> root to the real root window (i.e. the window manager).
>
> That makes it possible to remove the "workspace switch by scroll on 
> background" feature from the xfdesktop implementation and solely rely 
> on the window manager to implement it.
>
> Together with my other patch from yesterday, said feature is now 
> optional and enabled by default.
>
> Patch against current CVS attached. Works here, but I may have missed 
> some finer points.
>
>------------------------------------------------------------------------
>
>Index: src/main.c
>===================================================================
>RCS file: /cvsroot/xfce/xfce4/xfdesktop/src/main.c,v
>retrieving revision 1.52
>diff -u -r1.52 main.c
>--- src/main.c	20 Sep 2004 01:56:50 -0000	1.52
>+++ src/main.c	23 Sep 2004 18:50:13 -0000
>@@ -78,45 +78,91 @@
> 	gtk_main_quit();
> }
> 
>-static gboolean
>-scroll_cb(GtkWidget *w, GdkEventScroll *evt, gpointer user_data)
>+/**
>+ * forward_to_rootwindow
>+ * @event: The GDK event to forward.
>+ *
>+ * Forwards a GDK event to the root window using one or two X events.
>+ */
>+static void
>+forward_to_rootwindow(GdkEvent *event)
> {
>-	GdkScrollDirection dir = evt->direction;
>-	GdkScreen *gscreen;
>-	NetkScreen *netk_screen;
>-	NetkWorkspace *ws = NULL;
>-	gint n, active;
>-	
>-	gscreen = gtk_widget_get_screen(w);
>-	netk_screen = netk_screen_get(gdk_screen_get_number(gscreen));
>-	n = netk_screen_get_workspace_count(netk_screen);
>-	if(n <= 1)
>-		return FALSE;
>-	
>-	ws = netk_screen_get_active_workspace(netk_screen);
>-	active = netk_workspace_get_number(ws);
>-	
>-	switch(dir) {
>-		case GDK_SCROLL_UP:
>-		case GDK_SCROLL_LEFT:
>-			if(active == 0)
>-				active = n - 1;
>-			else
>-				active--;
>-			break;
>+	XButtonEvent xev;
>+	XButtonEvent xev2;
>+
>+	if ((event->type == GDK_BUTTON_PRESS) || (event->type == GDK_BUTTON_RELEASE))
>+	{
>+		if (event->type == GDK_BUTTON_PRESS)
>+		{
>+			xev.type = ButtonPress;
>+			/*
>+			 * rox has an option to disable the next
>+			 * instruction. it is called "blackbox_hack". Does
>+			 * anyone know why exactly it is needed?
>+			 */
>+			XUngrabPointer(GDK_DISPLAY(), event->button.time);
>+		}
>+		else
>+		{
>+			xev.type = ButtonRelease;
>+		}
>+		xev.button = event->button.button;
>+		xev.x = event->button.x;	/* Needed for icewm */
>+		xev.y = event->button.y;
>+		xev.x_root = event->button.x_root;
>+		xev.y_root = event->button.y_root;
>+		xev.state = event->button.state;
>+
>+		xev2.type = 0;
>+	}
>+	else if (event->type == GDK_SCROLL)
>+	{
>+		xev.type = ButtonPress;
>+		xev.button = event->scroll.direction + 4;
>+		xev.x = event->scroll.x;	/* Needed for icewm */
>+		xev.y = event->scroll.y;
>+		xev.x_root = event->scroll.x_root;
>+		xev.y_root = event->scroll.y_root;
>+		xev.state = event->scroll.state;
> 		
>-		case GDK_SCROLL_DOWN:
>-		case GDK_SCROLL_RIGHT:
>-			if(active == n - 1)
>-				active = 0;
>-			else
>-				active++;
>+		xev2.type = ButtonRelease;
>+		xev2.button = xev.button;
> 	}
>-	
>-	ws = netk_screen_get_workspace(netk_screen, active);
>-	netk_workspace_activate(ws);
>-	
>-	return FALSE;
>+	else
>+	{
>+		return;
>+	}
>+	xev.window = gdk_x11_get_default_root_xwindow();
>+	xev.root =  xev.window;
>+	xev.subwindow = None;
>+	xev.time = event->button.time;
>+	xev.same_screen = True;
>+
>+	XSendEvent(GDK_DISPLAY(), xev.window, False,
>+		ButtonPressMask | ButtonReleaseMask, (XEvent *) &xev);
>+	if (xev2.type == 0) return;
>+
>+	/* send button release for scroll event */
>+	xev2.window = xev.window;
>+	xev2.root = xev.root;
>+	xev2.subwindow = xev.subwindow;
>+	xev2.time = xev.time;
>+	xev2.x = xev.x;
>+	xev2.y = xev.y;
>+	xev2.x_root = xev.x_root;
>+	xev2.y_root = xev.y_root;
>+	xev2.state = xev.state;
>+	xev2.same_screen = xev.same_screen;
>+
>+	XSendEvent(GDK_DISPLAY(), xev2.window, False,
>+		ButtonPressMask | ButtonReleaseMask, (XEvent *) &xev2);
>+}
>+
>+static gboolean
>+scroll_cb(GtkWidget *w, GdkEventScroll *evt, gpointer user_data)
>+{
>+	forward_to_rootwindow((GdkEvent*)evt);
>+	return TRUE;
> }
> 
> static gboolean
>@@ -135,8 +181,9 @@
> 		popup_desktop_menu(gscreen, button, evt->time);
> 		return TRUE;
> 	}
>-	
>-	return FALSE;
>+	/* forward unused events to the root window, i.e. the window manager */
>+	forward_to_rootwindow((GdkEvent*)evt);
>+	return TRUE;
> }
> 
> static void
>@@ -288,6 +335,8 @@
> 				G_CALLBACK(scroll_cb), NULL);
> 		g_signal_connect(G_OBJECT(desktops[i]), "button-press-event",
> 			G_CALLBACK(button_cb), NULL);
>+		g_signal_connect(G_OBJECT(desktops[i]), "button-release-event",
>+			G_CALLBACK(button_cb), NULL);
> 		if(mcs_client)
> 			settings_register_callback(xfce_desktop_settings_changed, desktops[i]);
> 		gtk_widget_show(desktops[i]);
>  
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Xfce4-dev mailing list
>Xfce4-dev at xfce.org
>http://lunar-linux.org/mailman/listinfo/xfce4-dev
>



More information about the Xfce4-dev mailing list