Allow the panel's window list to be invoked externally & opened at the pointer. Signed-off-by: Darren Salt diff -urN xfce4-panel~/plugins/windowlist/Makefile.am xfce4-panel/plugins/windowlist/Makefile.am --- plugins/windowlist/Makefile.am 2006-07-31 21:06:58.000000000 +0100 +++ plugins/windowlist/Makefile.am 2006-07-31 20:16:59.000000000 +0100 @@ -1,3 +1,18 @@ +bin_PROGRAMS = xfce4-popup-windowlist + +xfce4_popup_windowlist_SOURCES = \ + xfce4-popup-windowlist.c \ + xfce4-popup-windowlist.h + +xfce4_popup_windowlist_CFLAGS = \ + $(LIBX11_CFLAGS) \ + $(GTK_CFLAGS) + +xfce4_popup_windowlist_LDADD = \ + $(LIBX11_LDFLAGS) \ + $(LIBX11_LIBS) \ + $(GTK_LIBS) + plugindir = $(libdir)/xfce4/panel-plugins plugin_LTLIBRARIES = libwindowlist.la @@ -10,7 +25,8 @@ windowlist.h \ windowlist.c \ windowlist-dialog.h \ - windowlist-dialog.c + windowlist-dialog.c \ + xfce4-popup-windowlist.h libwindowlist_la_CFLAGS = \ -I$(top_srcdir) \ diff -urN xfce4-panel~/plugins/windowlist/windowlist.c xfce4-panel/plugins/windowlist/windowlist.c --- plugins/windowlist/windowlist.c 2006-07-31 21:06:58.000000000 +0100 +++ plugins/windowlist/windowlist.c 2006-07-31 20:43:05.000000000 +0100 @@ -42,6 +42,7 @@ #include "windowlist.h" #include "windowlist-dialog.h" +#include "xfce4-popup-windowlist.h" static gboolean windowlist_blink (gpointer data); @@ -380,9 +381,9 @@ } static gboolean -menulist_toggle_menu (GtkToggleButton *button, - GdkEventButton *ev, - Windowlist * wl) +menulist_popup_menu (Windowlist * wl, + GdkEventButton *ev, + gboolean at_pointer) { GtkWidget *menu, *mi, *icon; NetkWindow *window; @@ -393,9 +394,6 @@ GList *windows, *li; PangoFontDescription *italic, *bold, *bold_italic; - if (ev->button != 1) - return FALSE; - /* Menu item styles */ italic = pango_font_description_from_string ("italic"); bold = pango_font_description_from_string ("bold"); @@ -571,7 +569,8 @@ } /* Activate toggle button */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wl->button), TRUE); + if (!at_pointer) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wl->button), TRUE); /* Connect signal, show widgets and popup */ g_signal_connect (menu, "deactivate", @@ -580,12 +579,23 @@ gtk_widget_show_all (menu); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, - (GtkMenuPositionFunc)windowlist_position_menu, - wl, 0, ev->time); + at_pointer ? NULL + : (GtkMenuPositionFunc)windowlist_position_menu, + wl, 0, ev ? ev->time : GDK_CURRENT_TIME); return TRUE; } +static gboolean +menulist_toggle_menu (GtkToggleButton *button, + GdkEventButton *ev, + Windowlist * wl) +{ + if (ev->button != 1) + return FALSE; + return menulist_popup_menu (wl, ev, FALSE); +} + /** * Check for urgent on workspaces **/ @@ -791,6 +801,65 @@ } /** + * Handle user messages + **/ +static gboolean +wl_message_received (GtkWidget *w, GdkEventClient *ev, gpointer user_data) +{ + Windowlist *wl = user_data; + GtkWidget *button = wl->button; + GdkScreen *gscreen = gtk_widget_get_screen (button); + GdkWindow *root = gdk_screen_get_root_window (gscreen); +/* + if (!xfdesktop_popup_grab_available (root, GDK_CURRENT_TIME)) + { + g_critical ("Unable to get keyboard/mouse grab."); + return FALSE; + } +*/ + if (ev->data_format == 8 && !strcmp (XFCE_WINDOW_LIST_MESSAGE, ev->data.b)) + return menulist_popup_menu (wl, NULL, FALSE); + + if (ev->data_format == 8 && !strcmp (XFCE_WINDOW_LIST_AT_POINTER_MESSAGE, ev->data.b)) + return menulist_popup_menu (wl, NULL, TRUE); + + return FALSE; +} + +static gboolean +wl_set_selection (Windowlist *wl) +{ + GdkScreen *gscreen; + gchar selection_name[32]; + Atom selection_atom; + GtkWidget *win; + Window xwin; + + win = gtk_invisible_new (); + gtk_widget_realize (win); + xwin = GDK_WINDOW_XID (GTK_WIDGET (win)->window); + + gscreen = gtk_widget_get_screen (win); + g_snprintf (selection_name, sizeof (selection_name), + XFCE_WINDOW_LIST_SELECTION"%d", gdk_screen_get_number (gscreen)); + selection_atom = XInternAtom (GDK_DISPLAY (), selection_name, False); + + if (XGetSelectionOwner (GDK_DISPLAY (), selection_atom)) + { + gtk_widget_destroy (win); + return FALSE; + } + + XSelectInput (GDK_DISPLAY (), xwin, PropertyChangeMask); + XSetSelectionOwner (GDK_DISPLAY (), selection_atom, xwin, GDK_CURRENT_TIME); + + g_signal_connect (G_OBJECT (win), "client-event", + G_CALLBACK (wl_message_received), wl); + + return TRUE; +} + +/** * Build the panel button and connect signals and styles **/ void @@ -857,7 +926,9 @@ g_signal_connect (wl->button, "state-changed", G_CALLBACK (windowlist_state_changed), wl); - + + wl_set_selection (wl); + gtk_widget_show_all (wl->button); gtk_container_add (GTK_CONTAINER (wl->plugin), wl->button); diff -urN xfce4-panel~/plugins/windowlist/xfce4-popup-windowlist.c xfce4-panel/plugins/windowlist/xfce4-popup-windowlist.c --- plugins/windowlist/xfce4-popup-windowlist.c 1970-01-01 01:00:00.000000000 +0100 +++ plugins/windowlist/xfce4-popup-windowlist.c 2006-07-31 20:12:08.000000000 +0100 @@ -0,0 +1,96 @@ +/* $Id$ + + 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + (c) 2006 Darren Salt + + Derived from xfdesktop's xfce4-popup-menu + (c) 2002-2006 Olivier Fourdan + + */ + +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include "xfce4-popup-windowlist.h" + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +gboolean +xfce4_check_is_running (GtkWidget *widget, Window *xid) +{ + GdkScreen *gscreen; + gchar selection_name[32]; + Atom selection_atom; + + gscreen = gtk_widget_get_screen (widget); + g_snprintf (selection_name, + sizeof (selection_name), + XFCE_WINDOW_LIST_SELECTION"%d", + gdk_screen_get_number (gscreen)); + selection_atom = XInternAtom (GDK_DISPLAY (), selection_name, False); + + if ((*xid = XGetSelectionOwner (GDK_DISPLAY (), selection_atom))) + return TRUE; + + return FALSE; +} + +int main (int argc, + char *argv[]) +{ + GdkEventClient gev; + GtkWidget *win; + Window id; + + gtk_init (&argc, &argv); + + win = gtk_invisible_new(); + gtk_widget_realize(win); + + gev.type = GDK_CLIENT_EVENT; + gev.window = win->window; + gev.send_event = TRUE; + gev.message_type = gdk_atom_intern ("STRING", FALSE); + gev.data_format = 8; + if (argc > 1 && !strcmp (argv[1], "-pointer")) + strcpy(gev.data.b, XFCE_WINDOW_LIST_AT_POINTER_MESSAGE); + else + strcpy(gev.data.b, XFCE_WINDOW_LIST_MESSAGE); + + if (xfce4_check_is_running (win, &id)) + gdk_event_send_client_message ((GdkEvent *)&gev, + (GdkNativeWindow)id); + else + g_warning ("Can't find the xfce4-panel window list to popup.\n"); + gdk_flush(); + + gtk_widget_destroy (win); + + return 0; +} diff -urN xfce4-panel~/plugins/windowlist/xfce4-popup-windowlist.h xfce4-panel/plugins/windowlist/xfce4-popup-windowlist.h --- plugins/windowlist/xfce4-popup-windowlist.h 1970-01-01 01:00:00.000000000 +0100 +++ plugins/windowlist/xfce4-popup-windowlist.h 2006-07-31 20:06:49.000000000 +0100 @@ -0,0 +1,43 @@ +/* $Id$ + + 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + + (c) 2006 Darren Salt + + Derived from xfdesktop panel-plugin/xfce4-popup-menu.h + (c) 2002-2006 Olivier Fourdan + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef INC_XFCE4_POPUP_MENU_H +#define INC_XFCE4_POPUP_MENU_H + +#ifndef XFCE_WINDOW_LIST_MESSAGE +#define XFCE_WINDOW_LIST_MESSAGE "xfce4-wndlist-popup" +#endif /* XFCE_MENU_MESSAGE */ + +#ifndef XFCE_WINDOW_LIST_AT_POINTER_MESSAGE +#define XFCE_WINDOW_LIST_AT_POINTER_MESSAGE "xfce4-wndlist-atptr" +#endif /* XFCE_MENU_MESSAGE */ + +#ifndef XFCE_WINDOW_LIST_SELECTION +#define XFCE_WINDOW_LIST_SELECTION "XFCE_WINDOW_LIST_SEL" +#endif /* XFCE_MENU_SELECTION */ + +#endif /* INC_XFCE4_POPUP_MENU_H */