Index: panel-plugin/desktop-menu-plugin.c =================================================================== --- panel-plugin/desktop-menu-plugin.c (revision 22219) +++ panel-plugin/desktop-menu-plugin.c (working copy) @@ -21,8 +21,14 @@ * Jean-Francois Wauthy (option panel for choice between icon/text) * Jasper Huijsmans (menu placement function, toggle button, scaled image * fixes) + * Olivier Fourdan (remote popup) */ +#include +#include +#include +#include + #ifdef HAVE_CONFIG_H #include #endif @@ -48,6 +54,8 @@ #include #include "desktop-menu-stub.h" +#include "xfdesktop-common.h" +#include "xfce4-popup-menu.h" #define BORDER 8 #define DEFAULT_BUTTON_ICON DATADIR "/pixmaps/xfce4_xicon1.png" @@ -328,26 +336,16 @@ g_signal_handler_disconnect(menu, id); } -static gboolean -dmp_popup(GtkWidget *w, - GdkEventButton *evt, - gpointer user_data) +static void +menu_activate(DMPlugin *dmp) { GtkWidget *menu; - DMPlugin *dmp = user_data; + GtkWidget *button; - if(evt->button != 1 || ((evt->state & GDK_CONTROL_MASK) - && !(evt->state & (GDK_MOD1_MASK|GDK_SHIFT_MASK - |GDK_MOD4_MASK)))) - { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), FALSE); - return FALSE; - } - + button = dmp->button; if(!dmp->desktop_menu) { g_critical("dmp->desktop_menu is NULL - module load failed?"); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), FALSE); - return TRUE; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE); } if(xfce_desktop_menu_need_update(dmp->desktop_menu)) @@ -360,14 +358,62 @@ id = g_signal_connect(menu, "deactivate", G_CALLBACK(menu_deactivated), dmp); g_object_set_data(G_OBJECT(menu), "sig_id", GUINT_TO_POINTER(id)); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), TRUE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); xfce_panel_plugin_register_menu (dmp->plugin, GTK_MENU(menu)); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, (GtkMenuPositionFunc)dmp_position_menu, dmp, 1, gtk_get_current_event_time()); } else + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE); +} + +static gboolean +dmp_message_received(GtkWidget *w, + GdkEventClient *evt, + gpointer user_data) +{ + DMPlugin *dmp = user_data; + GdkScreen *gscreen; + GdkWindow *root; + GtkWidget *button; + + button = dmp->button; + gscreen = gtk_widget_get_screen (button); + 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; + } + + if(evt->data_format == 8) { + if(strcmp(XFCE_MENU_MESSAGE, evt->data.b) == 0) { + menu_activate(dmp); + return TRUE; + } + } + + return FALSE; +} + +static gboolean +dmp_popup(GtkWidget *w, + GdkEventButton *evt, + gpointer user_data) +{ + GtkWidget *menu; + DMPlugin *dmp = user_data; + + if(evt->button != 1 || ((evt->state & GDK_CONTROL_MASK) + && !(evt->state & (GDK_MOD1_MASK|GDK_SHIFT_MASK + |GDK_MOD4_MASK)))) + { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), FALSE); + return FALSE; + } + menu_activate(dmp); + return TRUE; } @@ -872,10 +918,67 @@ gtk_widget_show(dlg); } +static gboolean +desktop_menu_plugin_check (GdkScreen *gscreen) +{ + gchar selection_name[32]; + Atom selection_atom; + + g_snprintf(selection_name, + sizeof(selection_name), + XFCE_MENU_SELECTION"%d", + gdk_screen_get_number (gscreen)); + selection_atom = XInternAtom(GDK_DISPLAY(), selection_name, False); + + if((XGetSelectionOwner(GDK_DISPLAY(), selection_atom))) + { + xfce_info (_("There is already a panel menu registered for this screen")); + return FALSE; + } + + return TRUE; +} + +static gboolean +dmp_set_selection(DMPlugin *dmp) +{ + 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_MENU_SELECTION"%d", + gdk_screen_get_number (gscreen)); + selection_atom = XInternAtom(GDK_DISPLAY(), selection_name, False); + + XSelectInput(GDK_DISPLAY(), xwin, PropertyChangeMask); + XSetSelectionOwner(GDK_DISPLAY(), selection_atom, xwin, GDK_CURRENT_TIME); + + if(XGetSelectionOwner(GDK_DISPLAY(), selection_atom) != xwin) { + g_warning("%s: could not set selection ownership", PACKAGE); + gtk_widget_destroy (win); + return FALSE; + } + + g_signal_connect(G_OBJECT(win), "client-event", + G_CALLBACK(dmp_message_received), dmp); + + return TRUE; +} + static DMPlugin * dmp_new(XfcePanelPlugin *plugin) { DMPlugin *dmp = g_new0(DMPlugin, 1); + dmp->plugin = plugin; dmp_read_config(plugin, dmp); @@ -915,7 +1018,8 @@ } g_signal_connect(G_OBJECT(dmp->button), "button-press-event", G_CALLBACK(dmp_popup), dmp); - + dmp_set_selection(dmp); + return dmp; } @@ -959,4 +1063,9 @@ dmp_set_size(plugin, xfce_panel_plugin_get_size(plugin), dmp); } +#if 0 XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL(desktop_menu_plugin_construct) +#else +XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL_WITH_CHECK (desktop_menu_plugin_construct, + desktop_menu_plugin_check) +#endif Index: panel-plugin/Makefile.am =================================================================== --- panel-plugin/Makefile.am (revision 22219) +++ panel-plugin/Makefile.am (working copy) @@ -6,6 +6,7 @@ xfce4_menu_plugin_CFLAGS = \ -I$(top_srcdir)/common \ + @LIBX11_CFLAGS@ \ @LIBXFCEGUI4_CFLAGS@ \ @LIBXFCE4PANEL_CFLAGS@ \ -DDATADIR=\"$(datadir)\" \ @@ -14,15 +15,32 @@ xfce4_menu_plugin_LDADD = \ $(top_builddir)/common/libxfdesktop-menu.la \ + $(top_builddir)/common/libxfdesktop.la \ + @LIBX11_LIBS@ \ @LIBXFCEGUI4_LIBS@ \ @LIBXFCE4PANEL_LIBS@ if HAVE_CYGWIN - xfce4_menu_plugin_LDFLAGS = \ +xfce4_menu_plugin_LDFLAGS = \ -no-undefined \ -export-symbols $(datadir)/xfce4/devel/panel.def endif + +bin_PROGRAMS = xfce4-popup-menu + +xfce4_popup_menu_SOURCES = \ + xfce4-popup-menu.h \ + xfce4-popup-menu.c + +xfce4_popup_menu_CFLAGS = \ + @LIBX11_CFLAGS@ \ + @GTK_CFLAGS@ + +xfce4_popup_menu_LDADD = \ + @LIBX11_LIBS@ \ + @GTK_LIBS@ + # .desktop file # # Some automake trickery here. Because we cannot use $(libexecdir) in the