Re: WM <--> panel protocol



Hey,

On Tue, 2003-02-11 at 15:33, Havoc Pennington wrote:

> > _GNOME_DOCK_ACTION Protocol
> > 
> >   The _GNOME_DOCK_ACTION WM_PROTOCOL is a simple mechanism
> >   whereby the window manager may invoke one of a number of
> >   actions on a DOCK type toplevel window (as advertised by
> >   the _NET_WM_WINDOW_TYPE hint).
> 
> Doesn't seem all that dock-specific really. Perhaps it should just 
> be _GNOME_DESKTOP_ACTION and go to the root window.
> 
> As long as it's _GNOME private though it probably doesn't matter a
> whole lot, assuming the panel exists and handles this stuff itself is
> fine.
>  
> >     _GNOME_DOCK_ACTION_MAIN_MENU, ATOM
> >     _GNOME_DOCK_ACTION_RUN_DIALOG, ATOM
> >     _GNOME_DOCK_ACTION_SCREENSHOT, ATOM
> >     _GNOME_DOCK_ACTION_WINDOW_SCREENSHOT, ATOM
> 
> For screenshot, I'd just use the metacity run_command bindings
> perhaps. The only downside to that is making configuring that binding
> a slightly more technical/advanced thing to do. But given that
> PrintScreen is hardcoded in every windows app ever and PrintScreen has
> no other useful purpose (other than perhaps some kernel debugging
> thing), I would feel pretty safe here.

	Good points. I've done that - updated patches/doc attached.

Good Luck,
Mark.
Index: display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.177
diff -u -p -r1.177 display.c
--- display.c	28 Jan 2003 15:07:43 -0000	1.177
+++ display.c	14 Feb 2003 04:09:32 -0000
@@ -266,7 +266,10 @@ meta_display_open (const char *name)
     "_NET_STARTUP_ID",
     "_METACITY_TOGGLE_VERBOSE",
     "_METACITY_UPDATE_COUNTER",
-    "SYNC_COUNTER"
+    "SYNC_COUNTER",
+    "_GNOME_PANEL_ACTION",
+    "_GNOME_PANEL_ACTION_MAIN_MENU",
+    "_GNOME_PANEL_ACTION_RUN_DIALOG"
   };
   Atom atoms[G_N_ELEMENTS(atom_names)];
   
@@ -406,6 +409,9 @@ meta_display_open (const char *name)
   display->atom_metacity_toggle_verbose = atoms[78];
   display->atom_metacity_update_counter = atoms[79];
   display->atom_sync_counter = atoms[80];
+  display->atom_gnome_panel_action = atoms[81];
+  display->atom_gnome_panel_action_main_menu = atoms[82];
+  display->atom_gnome_panel_action_run_dialog = atoms[83];
   
   display->prop_hooks = NULL;
   meta_display_init_window_prop_hooks (display);
Index: display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.98
diff -u -p -r1.98 display.h
--- display.h	28 Jan 2003 15:07:43 -0000	1.98
+++ display.h	14 Feb 2003 04:09:33 -0000
@@ -169,6 +169,9 @@ struct _MetaDisplay
   Atom atom_metacity_toggle_verbose;
   Atom atom_metacity_update_counter;
   Atom atom_sync_counter;
+  Atom atom_gnome_panel_action;
+  Atom atom_gnome_panel_action_main_menu;
+  Atom atom_gnome_panel_action_run_dialog;
   
   /* This is the actual window from focus events,
    * not the one we last set
Index: keybindings.c
===================================================================
RCS file: /cvs/gnome/metacity/src/keybindings.c,v
retrieving revision 1.76
diff -u -p -r1.76 keybindings.c
--- keybindings.c	21 Jan 2003 22:40:25 -0000	1.76
+++ keybindings.c	14 Feb 2003 04:09:38 -0000
@@ -79,6 +79,11 @@ static void handle_toggle_desktop     (M
                                        MetaWindow     *window,
                                        XEvent         *event,
                                        MetaKeyBinding *binding);
+static void handle_panel_keybinding   (MetaDisplay    *display,
+                                       MetaScreen     *screen,
+                                       MetaWindow     *window,
+                                       XEvent         *event,
+                                       MetaKeyBinding *binding);
 static void handle_toggle_maximize    (MetaDisplay    *display,
                                        MetaScreen     *screen,
                                        MetaWindow     *window,
@@ -265,6 +270,10 @@ static const MetaKeyHandler screen_handl
     GINT_TO_POINTER (META_TAB_LIST_DOCKS) },  
   { META_KEYBINDING_SHOW_DESKTOP, handle_toggle_desktop,
     NULL },
+  { META_KEYBINDING_PANEL_MAIN_MENU, handle_panel_keybinding,
+    GINT_TO_POINTER (META_KEYBINDING_ACTION_PANEL_MAIN_MENU) },
+  { META_KEYBINDING_PANEL_RUN_DIALOG, handle_panel_keybinding,
+    GINT_TO_POINTER (META_KEYBINDING_ACTION_PANEL_RUN_DIALOG) },
   { META_KEYBINDING_COMMAND_1, handle_run_command,
     GINT_TO_POINTER (0) },
   { META_KEYBINDING_COMMAND_2, handle_run_command,
@@ -329,6 +338,10 @@ static const MetaKeyHandler screen_handl
     GINT_TO_POINTER (30) },
   { META_KEYBINDING_COMMAND_32, handle_run_command,
     GINT_TO_POINTER (31) },
+  { META_KEYBINDING_COMMAND_SCREENSHOT, handle_run_command,
+    GINT_TO_POINTER (32) },
+  { META_KEYBINDING_COMMAND_WIN_SCREENSHOT, handle_run_command,
+    GINT_TO_POINTER (33) },
   { NULL, NULL, NULL }
 };
   
@@ -1017,6 +1030,14 @@ meta_window_grab_keys (MetaWindow  *wind
 {
   if (window->all_keys_grabbed)
     return;
+
+  if (window->type == META_WINDOW_DOCK)
+    {
+      if (window->keys_grabbed)
+        ungrab_all_keys (window->display, window->xwindow);
+      window->keys_grabbed = FALSE;
+      return;
+    }
   
   if (window->keys_grabbed)
     {
@@ -2514,6 +2535,48 @@ handle_toggle_desktop (MetaDisplay    *d
     meta_screen_unshow_desktop (screen);
   else
     meta_screen_show_desktop (screen);
+}
+
+static void
+handle_panel_keybinding (MetaDisplay    *display,
+                         MetaScreen     *screen,
+                         MetaWindow     *window,
+                         XEvent         *event,
+                         MetaKeyBinding *binding)
+{
+  MetaKeyBindingAction action;
+  Atom action_atom;
+  XClientMessageEvent ev;
+  
+  action = GPOINTER_TO_INT (binding->handler->data);
+
+  action_atom = None;
+  switch (action)
+    {
+    case META_KEYBINDING_ACTION_PANEL_MAIN_MENU:
+      action_atom = display->atom_gnome_panel_action_main_menu;
+      break;
+    case META_KEYBINDING_ACTION_PANEL_RUN_DIALOG:
+      action_atom = display->atom_gnome_panel_action_run_dialog;
+      break;
+    default:
+      return;
+    }
+   
+  ev.type = ClientMessage;
+  ev.window = screen->xroot;
+  ev.message_type = display->atom_gnome_panel_action;
+  ev.format = 32;
+  ev.data.l[0] = action_atom;
+  ev.data.l[1] = event->xkey.time;
+
+  meta_error_trap_push (display);
+  XSendEvent (display->xdisplay,
+	      screen->xroot,
+	      False,
+	      StructureNotifyMask,
+	      (XEvent*) &ev);
+  meta_error_trap_pop (display, FALSE);
 }
 
 static void
Index: metacity.schemas.in
===================================================================
RCS file: /cvs/gnome/metacity/src/metacity.schemas.in,v
retrieving revision 1.26
diff -u -p -r1.26 metacity.schemas.in
--- metacity.schemas.in	31 Jan 2003 03:57:01 -0000	1.26
+++ metacity.schemas.in	14 Feb 2003 04:09:41 -0000
@@ -1600,6 +1600,100 @@ you set
     </schema>
 
     <schema>
+      <key>/schemas/apps/metacity/global_keybindings/panel_main_menu</key>
+      <applyto>/apps/metacity/global_keybindings/panel_main_menu</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>&lt;Alt&gt;F1</default>
+      <locale name="C">
+         <short>Show the panel menu</short>
+         <long>
+          The keybinding which shows the panel's main menu.
+
+          The format looks like "&lt;Control&gt;a" or
+          "&lt;Shift&gt;&lt;Alt&gt;F1.
+
+          The parser is fairly liberal and allows lower or upper case,
+          and also abbreviations such as "&lt;Ctl&gt;" and
+          "&lt;Ctrl&gt;". If you set the option to the special string
+          "disabled", then there will be no keybinding for this
+          action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/metacity/global_keybindings/panel_run_dialog</key>
+      <applyto>/apps/metacity/global_keybindings/panel_run_dialog</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>&lt;Alt&gt;F2</default>
+      <locale name="C">
+         <short>Show the panel run dialog</short>
+         <long>
+          The keybinding which display's the panel's "Run Program" dialog
+          box.
+
+          The format looks like "&lt;Control&gt;a" or
+          "&lt;Shift&gt;&lt;Alt&gt;F1.
+
+          The parser is fairly liberal and allows lower or upper case,
+          and also abbreviations such as "&lt;Ctl&gt;" and
+          "&lt;Ctrl&gt;". If you set the option to the special string
+          "disabled", then there will be no keybinding for this
+          action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/metacity/global_keybindings/run_command_screenshot</key>
+      <applyto>/apps/metacity/global_keybindings/run_command_screenshot</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>Print</default>
+      <locale name="C">
+         <short>Take a screenshot</short>
+         <long>
+          The keybinding which invokes the panel's screenshot utility.
+
+          The format looks like "&lt;Control&gt;a" or
+          "&lt;Shift&gt;&lt;Alt&gt;F1.
+
+          The parser is fairly liberal and allows lower or upper case,
+          and also abbreviations such as "&lt;Ctl&gt;" and
+          "&lt;Ctrl&gt;". If you set the option to the special string
+          "disabled", then there will be no keybinding for this
+          action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/metacity/global_keybindings/run_command_window_screenshot</key>
+      <applyto>/apps/metacity/global_keybindings/run_command_window_screenshot</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>&lt;Alt&gt;Print</default>
+      <locale name="C">
+         <short>Take a screenshot of a window</short>
+         <long>
+          The keybinding which invokes the panel's screenshot utility
+          to take a screenshot of a window.
+
+          The format looks like "&lt;Control&gt;a" or
+          "&lt;Shift&gt;&lt;Alt&gt;F1.
+
+          The parser is fairly liberal and allows lower or upper case,
+          and also abbreviations such as "&lt;Ctl&gt;" and
+          "&lt;Ctrl&gt;". If you set the option to the special string
+          "disabled", then there will be no keybinding for this
+          action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/metacity/global_keybindings/run_command</key>
       <applyto>/apps/metacity/global_keybindings/run_command_1</applyto>
       <applyto>/apps/metacity/global_keybindings/run_command_2</applyto>
@@ -1635,6 +1729,38 @@ you set
     </schema>
 
     <!-- commands to run with the run_command keybindings -->
+
+    <schema>
+      <key>/schemas/apps/metacity/keybinding_commands/command_screenshot</key>
+      <applyto>/apps/metacity/keybinding_commands/command_screenshot</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>gnome-panel-screenshot</default>
+      <locale name="C">
+         <short>The screenshot command</short>
+         <long>
+         The /apps/metacity/global_keybindings/run_command_screenshot
+         key defines a keybinding which causes the command specified
+         by this setting to be invoked.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/metacity/keybinding_commands/command_window_screenshot</key>
+      <applyto>/apps/metacity/keybinding_commands/command_window_screenshot</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>gnome-panel-screenshot --window</default>
+      <locale name="C">
+         <short>The window screenshot command</short>
+         <long>
+         The /apps/metacity/global_keybindings/run_command_window_screenshot
+         key defines a keybinding which causes the command specified
+         by this setting to be invoked.
+         </long>
+      </locale>
+    </schema>
 
     <schema>
       <key>/schemas/apps/metacity/keybinding_commands/command</key>
Index: prefs.c
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.c,v
retrieving revision 1.40
diff -u -p -r1.40 prefs.c
--- prefs.c	28 Jan 2003 15:07:43 -0000	1.40
+++ prefs.c	14 Feb 2003 04:09:44 -0000
@@ -30,7 +30,11 @@
 #include <stdlib.h>
 
 #define MAX_REASONABLE_WORKSPACES 32
-#define MAX_COMMANDS 32
+
+#define MAX_COMMANDS (32 + NUM_EXTRA_COMMANDS)
+#define NUM_EXTRA_COMMANDS 2
+#define SCREENSHOT_COMMAND_IDX (MAX_COMMANDS - 2)
+#define WIN_SCREENSHOT_COMMAND_IDX (MAX_COMMANDS - 1)
 
 /* If you add a key, it needs updating in init() and in the gconf
  * notify listener and of course in the .schemas file
@@ -95,6 +99,7 @@ static MetaButtonLayout button_layout = 
   }
 };
 
+/* The screenshot commands are at the end */
 static char *commands[MAX_COMMANDS] = { NULL, };
 
 static char *workspace_names[MAX_REASONABLE_WORKSPACES] = { NULL, };
@@ -1363,6 +1368,8 @@ static MetaKeyPref screen_bindings[] = {
   { META_KEYBINDING_CYCLE_PANELS, 0, 0 },
   { META_KEYBINDING_CYCLE_PANELS_BACKWARD, 0, 0 },
   { META_KEYBINDING_SHOW_DESKTOP, 0, 0 },
+  { META_KEYBINDING_PANEL_MAIN_MENU, 0, 0 },
+  { META_KEYBINDING_PANEL_RUN_DIALOG, 0, 0 },
   { META_KEYBINDING_COMMAND_1, 0, 0 },
   { META_KEYBINDING_COMMAND_2, 0, 0 },
   { META_KEYBINDING_COMMAND_3, 0, 0 },
@@ -1395,6 +1402,8 @@ static MetaKeyPref screen_bindings[] = {
   { META_KEYBINDING_COMMAND_30, 0, 0 },
   { META_KEYBINDING_COMMAND_31, 0, 0 },
   { META_KEYBINDING_COMMAND_32, 0, 0 },
+  { META_KEYBINDING_COMMAND_SCREENSHOT, 0, 0 },
+  { META_KEYBINDING_COMMAND_WIN_SCREENSHOT, 0, 0 },
   { NULL, 0, 0 }
 };
 
@@ -1663,15 +1672,31 @@ update_command (const char  *name,
   
   ++p;
 
-  if (!g_ascii_isdigit (*p))
+  if (g_ascii_isdigit (*p))
     {
-      meta_topic (META_DEBUG_KEYBINDINGS,
-                  "Command %s doesn't end in number?\n", name);
-      return FALSE;
+      i = atoi (p);
+      i -= 1; /* count from 0 not 1 */
+    }
+  else
+    {
+      p = strrchr (name, '/');
+      ++p;
+
+      if (strcmp (p, "command_screenshot") == 0)
+        {
+          i = SCREENSHOT_COMMAND_IDX;
+        }
+      else if (strcmp (p, "command_window_screenshot") == 0)
+        {
+          i = WIN_SCREENSHOT_COMMAND_IDX;
+        }
+      else
+        {
+          meta_topic (META_DEBUG_KEYBINDINGS,
+                      "Command %s doesn't end in number?\n", name);
+          return FALSE;
+        }
     }
-  
-  i = atoi (p);
-  i -= 1; /* count from 0 not 1 */
   
   if (i >= MAX_COMMANDS)
     {
@@ -1711,8 +1736,19 @@ char*
 meta_prefs_get_gconf_key_for_command (int i)
 {
   char *key;
-  
-  key = g_strdup_printf (KEY_COMMAND_PREFIX"%d", i + 1);
+
+  switch (i)
+    {
+    case SCREENSHOT_COMMAND_IDX:
+      key = g_strdup (KEY_COMMAND_PREFIX "screenshot");
+      break;
+    case WIN_SCREENSHOT_COMMAND_IDX:
+      key = g_strdup (KEY_COMMAND_PREFIX "window_screenshot");
+      break;
+    default:
+      key = g_strdup_printf (KEY_COMMAND_PREFIX"%d", i + 1);
+      break;
+    }
   
   return key;
 }
Index: prefs.h
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.h,v
retrieving revision 1.29
diff -u -p -r1.29 prefs.h
--- prefs.h	28 Jan 2003 15:07:43 -0000	1.29
+++ prefs.h	14 Feb 2003 04:09:45 -0000
@@ -109,6 +109,8 @@ void        meta_prefs_change_workspace_
 #define META_KEYBINDING_CYCLE_PANELS             "cycle_panels"
 #define META_KEYBINDING_CYCLE_PANELS_BACKWARD    "cycle_panels_backward"
 #define META_KEYBINDING_SHOW_DESKTOP             "show_desktop"
+#define META_KEYBINDING_PANEL_MAIN_MENU          "panel_main_menu"
+#define META_KEYBINDING_PANEL_RUN_DIALOG         "panel_run_dialog"
 #define META_KEYBINDING_COMMAND_1                "run_command_1"
 #define META_KEYBINDING_COMMAND_2                "run_command_2"
 #define META_KEYBINDING_COMMAND_3                "run_command_3"
@@ -141,6 +143,8 @@ void        meta_prefs_change_workspace_
 #define META_KEYBINDING_COMMAND_30               "run_command_30"
 #define META_KEYBINDING_COMMAND_31               "run_command_31"
 #define META_KEYBINDING_COMMAND_32               "run_command_32"
+#define META_KEYBINDING_COMMAND_SCREENSHOT       "run_command_screenshot"
+#define META_KEYBINDING_COMMAND_WIN_SCREENSHOT   "run_command_window_screenshot"
 
 /* Window bindings */
 #define META_KEYBINDING_WINDOW_MENU              "activate_window_menu"
@@ -204,6 +208,8 @@ typedef enum _MetaKeyBindingAction
   META_KEYBINDING_ACTION_CYCLE_PANELS,
   META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
   META_KEYBINDING_ACTION_SHOW_DESKTOP,
+  META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
+  META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
   META_KEYBINDING_ACTION_COMMAND_1,
   META_KEYBINDING_ACTION_COMMAND_2,
   META_KEYBINDING_ACTION_COMMAND_3,
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/Makefile.am,v
retrieving revision 1.307
diff -u -p -r1.307 Makefile.am
--- Makefile.am	12 Jan 2003 04:08:46 -0000	1.307
+++ Makefile.am	14 Feb 2003 04:08:51 -0000
@@ -119,7 +119,6 @@ panel_sources =			\
 	panel-config-global.c  	\
 	panel-util.c		\
 	panel-gconf.c		\
-	global-keys.c		\
 	panel-config.c  	\
 	distribution.c		\
 	gnome-run.c  		\
@@ -139,6 +138,7 @@ panel_sources =			\
 	panel-menu-bar.c        \
 	panel-recent.c		\
 	panel-gdk-pixbuf-extensions.c \
+	panel-action-protocol.c	\
 	$(EGG_RECENT_FILES_C)	\
 	$(NULL)
 
@@ -163,7 +163,6 @@ panel_headers =			\
 	applet.h         	\
 	drawer.h  		\
 	panel-util.h		\
-	global-keys.h		\
 	panel-config.h		\
 	panel-config-global.h  	\
 	panel-gconf.h		\
@@ -184,6 +183,7 @@ panel_headers =			\
 	panel-menu-bar.h        \
 	panel-recent.h		\
 	panel-gdk-pixbuf-extensions.h \
+	panel-action-protocol.h	\
 	$(EGG_RECENT_FILES_H)	\
 	$(NULL)
 
Index: global-keys.c
===================================================================
RCS file: global-keys.c
diff -N global-keys.c
--- global-keys.c	21 Jan 2003 08:45:37 -0000	1.38
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,371 +0,0 @@
-#include <config.h>
-
-#include <X11/keysym.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdk.h>
-
-#include <libgnome/libgnome.h>
-
-#include "global-keys.h"
-
-#include "applet.h"
-#include "gnome-run.h"
-#include "panel.h"
-#include "menu.h"
-#include "panel-util.h"
-#include "egg-screen-exec.h"
-#include "eggaccelerators.h"
-#include "xstuff.h"
-
-extern GlobalConfig global_config;
-extern GSList *panels;
-
-#define N_BITS 32 /*all modifier masks fit into it */
-
-typedef struct {
-	guint mods;
-	guint key;
-} ModAndKey;
-typedef void (*BitsCallback) (guint value, ModAndKey *mod_and_key);
-
-static guint
-get_ignored_mods (void)
-{
-  guint ignored_mods;
-
-  ignored_mods = 0;
-  egg_keymap_resolve_virtual_modifiers (gdk_keymap_get_default (),
-                                        EGG_VIRTUAL_NUM_LOCK_MASK |
-                                        EGG_VIRTUAL_SCROLL_LOCK_MASK,
-                                        &ignored_mods);
-
-  return ignored_mods;
-}
-
-static void
-all_combinations (guint mask_to_traverse,
-		  BitsCallback callback,
-		  ModAndKey *mod_and_key)
-{
-	int indexes[N_BITS];/*indexes of bits we need to flip*/
-	int i, bit, bits_set_cnt;
-	int uppervalue;
-
-	bit = 0;
-	for (i = 0; i < N_BITS; i++) {
-		if (mask_to_traverse & (1<<i))
-			indexes[bit++]=i;
-	}
-
-	bits_set_cnt = bit;
-
-	uppervalue = 1<<bits_set_cnt;
-	for (i = 0; i < uppervalue; i++) {
-		int j, result = 0;
-
-		for (j = 0; j < bits_set_cnt; j++) {
-			if (i & (1<<j))
-				result |= (1<<indexes[j]);
-		}
-		callback (result, mod_and_key);
-	}
-}
-
-static void
-do_grab_key (guint mod, ModAndKey* data)
-{
-	xstuff_grab_key_on_all_screens (data->key, (mod | data->mods), TRUE);
-}
-
-static void
-grab_key (guint mod, guint key)
-{
-	ModAndKey data;
-        guint ignored_mods;
-        int other_mods;
-
-        ignored_mods = get_ignored_mods ();
-        
-        other_mods = ignored_mods & ~mod;
-    
-	data.mods = mod;
-        data.key = key;
-    
-	all_combinations (other_mods, do_grab_key, &data);
-}
-
-static void
-do_ungrab_key (guint mod, ModAndKey* data)
-{
-	xstuff_grab_key_on_all_screens (data->key, (mod | data->mods), FALSE);
-}
-
-static void 
-ungrab_key (guint mod,guint key)
-{
-	ModAndKey data;
-        guint ignored_mods;
-        int other_mods;
-
-        /* FIXME this is broken as the modifiers may have changed
-         * between the grab and the ungrab.
-         */
-        ignored_mods = get_ignored_mods ();
-        
-        other_mods = ignored_mods & ~mod;
-    
-	data.mods = mod;
-	data.key = key;
-    
-	all_combinations(other_mods, do_ungrab_key, &data);
-}
-
-void
-panel_global_keys_setup (void)
-{
-	static guint lastkey_menu = 0;
-	static guint laststate_menu = 0;
-	static guint lastkey_run = 0;
-	static guint laststate_run = 0;
-	static guint lastkey_screenshot = 0;
-	static guint laststate_screenshot = 0;
-	static guint lastkey_window_screenshot = 0;
-	static guint laststate_window_screenshot = 0;
-
-	/* FIXME: the if trees are horrible, this shoul dbe cleaned up with
-	 * lists or something */
-
-	gdk_error_trap_push();
-	if (lastkey_menu != 0) {
-		ungrab_key (laststate_menu, lastkey_menu);
-	}
-	if (lastkey_run != 0 &&
-	    (lastkey_menu != lastkey_run ||
-	     laststate_menu != laststate_run)) {
-		ungrab_key (laststate_run, lastkey_run);
-	}
-	if (lastkey_run != 0 &&
-	    (lastkey_menu != lastkey_screenshot ||
-	     laststate_menu != laststate_screenshot) &&
-	    (lastkey_run != lastkey_screenshot ||
-	     laststate_run != laststate_screenshot)) {
-		ungrab_key (laststate_screenshot, lastkey_screenshot);
-	}
-	if (lastkey_run != 0 &&
-	    (lastkey_menu != lastkey_window_screenshot ||
-	     laststate_menu != laststate_window_screenshot) &&
-	    (lastkey_run != lastkey_window_screenshot ||
-	     laststate_run != laststate_window_screenshot) &&
-	    (lastkey_screenshot != lastkey_window_screenshot ||
-	     laststate_screenshot != laststate_window_screenshot)) {
-		ungrab_key (laststate_window_screenshot,
-			    lastkey_window_screenshot);
-	}
-	
-	if (global_config.keys_enabled && 
-	    global_config.menu_key.keysym) {
-		lastkey_menu = XKeysymToKeycode(GDK_DISPLAY(),
-						global_config.menu_key.keysym);
-		laststate_menu = global_config.menu_key.state;
-		if (lastkey_menu != 0)
-			grab_key (laststate_menu, lastkey_menu);
-	} else {
-		lastkey_menu = 0;
-	}
-
-	if (global_config.keys_enabled && 
-	    global_config.run_key.keysym) {
-		lastkey_run = XKeysymToKeycode (GDK_DISPLAY (),
-						global_config.run_key.keysym);
-		laststate_run = global_config.run_key.state;
-		if (lastkey_run != 0 &&
-		    (lastkey_menu != lastkey_run ||
-		     laststate_menu != laststate_run))
-			grab_key (laststate_run, lastkey_run);
-	} else {
-		lastkey_run = 0;
-	}
-
-	if (global_config.keys_enabled && 
-	    global_config.screenshot_key.keysym) {
-		lastkey_screenshot = XKeysymToKeycode
-			(GDK_DISPLAY (), global_config.screenshot_key.keysym);
-		laststate_screenshot = global_config.screenshot_key.state;
-		if (lastkey_screenshot != 0 &&
-		    (lastkey_menu != lastkey_screenshot ||
-		     laststate_menu != laststate_screenshot) &&
-		    (lastkey_run != lastkey_screenshot ||
-		     laststate_run != laststate_screenshot))
-			grab_key (laststate_screenshot, lastkey_screenshot);
-	} else {
-		lastkey_screenshot = 0;
-	}
-
-	if (global_config.keys_enabled && 
-	    global_config.window_screenshot_key.keysym) {
-		lastkey_window_screenshot = XKeysymToKeycode
-			(GDK_DISPLAY (), global_config.window_screenshot_key.keysym);
-		laststate_window_screenshot = global_config.window_screenshot_key.state;
-		if (lastkey_window_screenshot != 0 &&
-		    (lastkey_menu != lastkey_window_screenshot ||
-		     laststate_menu != laststate_window_screenshot) &&
-		    (lastkey_run != lastkey_window_screenshot ||
-		     laststate_run != laststate_window_screenshot) &&
-		    (lastkey_screenshot != lastkey_window_screenshot ||
-		     laststate_screenshot != laststate_window_screenshot))
-			grab_key (laststate_window_screenshot,
-				  lastkey_window_screenshot);
-	} else {
-		lastkey_window_screenshot = 0;
-	}
-
-	gdk_flush ();
-	gdk_error_trap_pop();
-}
-
-static gboolean
-check_for_grabs (void)
-{
-	if (gdk_pointer_grab (gdk_get_default_root_window (), FALSE, 
-			      0, NULL, NULL, GDK_CURRENT_TIME)
-	    != GrabSuccess) {
-		return TRUE;
-	} else {
-		gdk_pointer_ungrab (GDK_CURRENT_TIME);
-		return FALSE;
-	}
-}
-
-GdkFilterReturn
-panel_global_keys_filter (GdkXEvent *gdk_xevent,
-			  GdkEvent  *event,
-			  GdkScreen *screen)
-{
-	XEvent *xevent = (XEvent *)gdk_xevent;
-	guint keycode, state;
-	guint menu_keycode, menu_state;
-	guint run_keycode, run_state;
-	guint screenshot_keycode, screenshot_state;
-	guint window_screenshot_keycode, window_screenshot_state;
-        guint ignored_mods;
-
-	g_return_val_if_fail (GDK_IS_SCREEN (screen), GDK_FILTER_CONTINUE);
-        
-	if(xevent->type != KeyPress)
-		return GDK_FILTER_CONTINUE;
-
-        ignored_mods = get_ignored_mods ();
-        
-	keycode = xevent->xkey.keycode;
-	state = xevent->xkey.state;
-
-	menu_keycode = XKeysymToKeycode (GDK_DISPLAY (),
-					 global_config.menu_key.keysym);
-	menu_state = global_config.menu_key.state;
-
-	run_keycode = XKeysymToKeycode (GDK_DISPLAY (),
-					global_config.run_key.keysym);
-	run_state = global_config.run_key.state;
-
-	screenshot_keycode = XKeysymToKeycode (GDK_DISPLAY (),
-					       global_config.screenshot_key.keysym);
-	screenshot_state = global_config.screenshot_key.state;
-
-	window_screenshot_keycode =
-		XKeysymToKeycode (GDK_DISPLAY (),
-				  global_config.window_screenshot_key.keysym);
-	window_screenshot_state = global_config.window_screenshot_key.state;
-
-	if (keycode == menu_keycode &&
-	    (state & (~ignored_mods)) == menu_state) {
-		PanelWidget *panel_widget;
-		GtkWidget   *panel;
-		GtkWidget   *menu;
-
-		/* check if anybody else has a grab */
-		if (check_for_grabs ())
-			return GDK_FILTER_CONTINUE;
-
-		panel_widget = panels->data;
-		menu = create_panel_root_menu (panel_widget);
-		panel = panel_widget->panel_parent;
-
-		BASEP_WIDGET (panel)->autohide_inhibit = TRUE;
-		basep_widget_autohide (BASEP_WIDGET (panel));
-
-		gtk_menu_set_screen (GTK_MENU (menu), screen);
-		gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
-				NULL, NULL, 0, GDK_CURRENT_TIME);
-		return GDK_FILTER_REMOVE;
-	} else if (keycode == run_keycode &&
-		   (state & (~ignored_mods)) == run_state) {
-		/* check if anybody else has a grab */
-		if (check_for_grabs ()) {
-			return GDK_FILTER_CONTINUE;
-		}
-
-		show_run_dialog (screen);
-		return GDK_FILTER_REMOVE;
-	} else if (keycode == screenshot_keycode &&
-		   (state & (~ignored_mods)) == screenshot_state) {
-		char *argv [2];
-		char *proggie;
-
-		/* check if anybody else has a grab */
-		if (check_for_grabs ()) {
-			return GDK_FILTER_CONTINUE;
-		}
-
-		proggie = g_find_program_in_path  ("gnome-panel-screenshot");
-		if (proggie == NULL) {
-			panel_error_dialog (
-				screen,
-				"cannot_find_ss_program",
-				_("Can't find the screenshot program"));
-			return GDK_FILTER_REMOVE;
-		}
-		argv[0] = proggie;
-		argv[1] = NULL;
-
-		if (egg_screen_execute_async (screen, g_get_home_dir (), 1, argv) < 0)
-			panel_error_dialog (screen,
-					    "cannot_exec_ss_program",
-					    _("Can't execute the screenshot program"));
-
-		g_free (proggie);
-
-		return GDK_FILTER_REMOVE;
-	} else if (keycode == window_screenshot_keycode &&
-		   (state & (~ignored_mods)) == window_screenshot_state) {
-		char *argv [3];
-		char *proggie;
-
-		/* check if anybody else has a grab */
-		if (check_for_grabs ()) {
-			return GDK_FILTER_CONTINUE;
-		}
-
-		proggie = g_find_program_in_path  ("gnome-panel-screenshot");
-		if (proggie == NULL) {
-			panel_error_dialog (
-				screen,
-				"cannot_find_ss_program",
-				_("Can't find the screenshot program"));
-			return GDK_FILTER_REMOVE;
-		}
-		argv[0] = proggie;
-		argv[1] = "--window";
-		argv[2] = NULL;
-
-		if (egg_screen_execute_async (screen, g_get_home_dir (), 2, argv) < 0)
-			panel_error_dialog (screen,
-					    "cannot_exec_ss_program",
-					    _("Can't execute the screenshot program"));
-
-		g_free (proggie);
-
-		return GDK_FILTER_REMOVE;
-	}
-
-	return GDK_FILTER_CONTINUE;
-}
Index: global-keys.h
===================================================================
RCS file: global-keys.h
diff -N global-keys.h
--- global-keys.h	6 Oct 2002 22:52:37 -0000	1.5
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,16 +0,0 @@
-#ifndef GLOBAL_KEYS_H
-#define GLOBAL_KEYS_H 1    
-
-/* WTF are these doing here */
-/*#define XK_LEFT_WIN 115
-#define XK_RIGHT_WIN 116
-#define XK_RIGHT_MENU 117*/
-
-#include <gdk/gdktypes.h>
-
-void		panel_global_keys_setup	 (void);
-GdkFilterReturn	panel_global_keys_filter (GdkXEvent *gdk_xevent,
-					  GdkEvent  *event,
-				          GdkScreen *screen);
-
-#endif
Index: main.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/main.c,v
retrieving revision 1.330
diff -u -p -r1.330 main.c
--- main.c	10 Jan 2003 01:19:51 -0000	1.330
+++ main.c	14 Feb 2003 04:08:57 -0000
@@ -30,7 +30,7 @@
 #include "session.h"
 #include "xstuff.h"
 #include "panel-stock-icons.h"
-#include "global-keys.h"
+#include "panel-action-protocol.h"
 
 extern int config_sync_timeout;
 
@@ -191,7 +191,7 @@ main(int argc, char **argv)
 
 	panel_tooltips = gtk_tooltips_new ();
 
-	xstuff_init ((GdkFilterFunc) panel_global_keys_filter);
+	panel_action_protocol_init ();
 	multiscreen_init ();
 	panel_init_stock_icons_and_items ();
 
Index: panel-action-protocol.c
===================================================================
RCS file: panel-action-protocol.c
diff -N panel-action-protocol.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ panel-action-protocol.c	14 Feb 2003 04:09:08 -0000
@@ -0,0 +1,128 @@
+/*
+ * panel-action-protocol.h: _GNOME_PANEL_ACTION protocol impl.
+ *
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *	Mark McLoughlin <mark skynet ie>
+ */
+
+#include <config.h>
+
+#include "panel-action-protocol.h"
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <X11/Xlib.h>
+#include <libgnome/gnome-i18n.h>
+
+#include "gnome-run.h"
+#include "menu.h"
+#include "basep-widget.h"
+#include "panel-util.h"
+#include "egg-screen-exec.h"
+
+static Atom atom_gnome_panel_action            = None;
+static Atom atom_gnome_panel_action_main_menu  = None;
+static Atom atom_gnome_panel_action_run_dialog = None;
+
+extern GSList *panels;
+
+static void
+panel_action_protocol_main_menu (GdkScreen *screen)
+{
+	PanelWidget *panel_widget;
+	GtkWidget   *panel;
+	GtkWidget   *menu;
+
+	panel_widget = panels->data;
+	menu = create_panel_root_menu (panel_widget);
+	panel = panel_widget->panel_parent;
+
+	BASEP_WIDGET (panel)->autohide_inhibit = TRUE;
+	basep_widget_autohide (BASEP_WIDGET (panel));
+
+	gtk_menu_set_screen (GTK_MENU (menu), screen);
+	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
+}
+
+static void
+panel_action_protocol_run_dialog (GdkScreen *screen)
+{
+	show_run_dialog (screen);
+}
+
+static GdkFilterReturn
+panel_action_protocol_filter (GdkXEvent *gdk_xevent,
+			      GdkEvent  *event,
+			      gpointer   data)
+{
+	GdkWindow *window;
+	GdkScreen *screen;
+	XEvent    *xevent = (XEvent *) gdk_xevent;
+
+	if (xevent->type != ClientMessage)
+		return GDK_FILTER_CONTINUE;
+
+	if (xevent->xclient.message_type != atom_gnome_panel_action)
+		return GDK_FILTER_CONTINUE;
+
+	window = gdk_window_lookup (xevent->xclient.window);
+	if (!window)
+		return GDK_FILTER_CONTINUE;
+
+	screen = gdk_drawable_get_screen (window);
+
+	if (xevent->xclient.data.l [0] == atom_gnome_panel_action_main_menu)
+		panel_action_protocol_main_menu (screen);
+	else if (xevent->xclient.data.l [0] == atom_gnome_panel_action_run_dialog)
+		panel_action_protocol_run_dialog (screen);
+	else
+		return GDK_FILTER_CONTINUE;
+
+	return GDK_FILTER_REMOVE;
+}
+
+void
+panel_action_protocol_init (void)
+{
+	GdkDisplay *display;
+	GdkAtom     gdk_atom_gnome_panel_action;
+
+	display = gdk_display_get_default ();
+
+	gdk_atom_gnome_panel_action =
+		gdk_atom_intern ("_GNOME_PANEL_ACTION", FALSE);
+
+	atom_gnome_panel_action =
+		XInternAtom (GDK_DISPLAY_XDISPLAY (display),
+			     "_GNOME_PANEL_ACTION",
+			     FALSE);
+	atom_gnome_panel_action_main_menu =
+		XInternAtom (GDK_DISPLAY_XDISPLAY (display),
+			     "_GNOME_PANEL_ACTION_MAIN_MENU",
+			     FALSE);
+	atom_gnome_panel_action_run_dialog =
+		XInternAtom (GDK_DISPLAY_XDISPLAY (display),
+			     "_GNOME_PANEL_ACTION_RUN_DIALOG",
+			     FALSE);
+
+	gdk_display_add_client_message_filter (
+		display, gdk_atom_gnome_panel_action,
+		panel_action_protocol_filter, NULL);
+}
Index: panel-action-protocol.h
===================================================================
RCS file: panel-action-protocol.h
diff -N panel-action-protocol.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ panel-action-protocol.h	14 Feb 2003 04:09:08 -0000
@@ -0,0 +1,36 @@
+/*
+ * panel-action-protocol.h: _GNOME_PANEL_ACTION protocol impl.
+ *
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Authors:
+ *	Mark McLoughlin <mark skynet ie>
+ */
+
+#ifndef __PANEL_ACTION_PROTOCOL_H__
+#define __PANEL_ACTION_PROTOCOL_H__
+
+#include <glib/gmacros.h>
+
+G_BEGIN_DECLS
+
+void panel_action_protocol_init (void);
+
+G_END_DECLS
+
+#endif /* __PANEL_ACTION_PROTOCOL_H__ */
Index: panel.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/panel.c,v
retrieving revision 1.502
diff -u -p -r1.502 panel.c
--- panel.c	31 Jan 2003 04:03:50 -0000	1.502
+++ panel.c	14 Feb 2003 04:09:14 -0000
@@ -46,7 +46,6 @@
 #include "panel-gconf.h"
 #include "session.h"
 #include "panel-applet-frame.h"
-#include "global-keys.h"
 #include "panel-action-button.h"
 #include "panel-menu-bar.h"
 #include "panel-compatibility.h"
@@ -2002,10 +2001,7 @@ panel_apply_global_config (void)
 
 		basep_update_frame (BASEP_WIDGET (pd->panel));
 	}
-
-	panel_global_keys_setup ();
 }
-
 
 static GtkWidget *
 panel_load_edge_panel_from_gconf (const char          *profile,
Index: xstuff.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/xstuff.c,v
retrieving revision 1.61
diff -u -p -r1.61 xstuff.c
--- xstuff.c	21 Jan 2003 08:45:37 -0000	1.61
+++ xstuff.c	14 Feb 2003 04:09:16 -0000
@@ -312,26 +312,6 @@ xstuff_delete_property (GdkWindow *windo
 			 panel_atom_get (name));
 }
 
-void
-xstuff_init (GdkFilterFunc keys_filter)
-{
-	GdkDisplay *display;
-	int         screens, i;
-
-	display = gdk_display_get_default ();
-	screens = gdk_display_get_n_screens (display);
-
-	for (i = 0; i < screens; i++) {
-		GdkScreen *screen;
-		GdkWindow *root_window;
-
-		screen = gdk_display_get_screen (display, i);
-		root_window = gdk_screen_get_root_window (screen);
-
-		gdk_window_add_filter (root_window, keys_filter, screen);
-	}
-}
-
 /* Zoom animation */
 #define MINIATURIZE_ANIMATION_FRAMES_Z   1
 #define MINIATURIZE_ANIMATION_STEPS_Z    6
Index: xstuff.h
===================================================================
RCS file: /cvs/gnome/gnome-panel/gnome-panel/xstuff.h,v
retrieving revision 1.27
diff -u -p -r1.27 xstuff.h
--- xstuff.h	21 Jan 2003 08:45:37 -0000	1.27
+++ xstuff.h	14 Feb 2003 04:09:16 -0000
@@ -4,7 +4,6 @@
 #include <gdk/gdk.h>
 #include <gtk/gtkwidget.h>
 
-void xstuff_init			(GdkFilterFunc keys_filter);
 void xstuff_delete_property		(GdkWindow *window,
 					 const char *name);
 gboolean xstuff_is_compliant_wm		(void);
_GNOME_PANEL_ACTION Protocol

  The _GNOME_PANEL_ACTION is a simple mechanism whereby an
  application window invoke one of a number of simple
  actions which will be handled by the GNOME panel. This
  protocol is intended to be used by window managers who
  provide keybindings for these actions.

  To invoke an action the application sends the following
  ClientMessage to the root window of the screen on which
  the keybinding was activated:

   type = ClientMessage
   window = the root window
   message_type = _GNOME_PANEL_ACTION
   format = 32
   data.l[0] = action
   data.l[1] = timestamp

  Possible action atoms are:

    _GNOME_PANEL_ACTION_MAIN_MENU, ATOM
    _GNOME_PANEL_ACTION_RUN_DIALOG, ATOM

  Unsupported actions are ignored by the panel.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]