[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