]> Dogcows Code - chaz/openbox/commitdiff
little bit of an actions overhaul, added action_run* so that duplicated code can...
authorDana Jansens <danakj@orodu.net>
Sun, 7 Sep 2003 19:03:20 +0000 (19:03 +0000)
committerDana Jansens <danakj@orodu.net>
Sun, 7 Sep 2003 19:03:20 +0000 (19:03 +0000)
allow actions to specify when they can be used (ShowMenu cant in the OB_USER_ACTION_MENU_SELECTION case)
remove KeyboardMove ad KeyboardResize. Instead, just use Move and Resize and determine if it should be a keyboard move/resize in the code

15 files changed:
data/rc.xml
openbox/action.c
openbox/action.h
openbox/client_list_menu.c
openbox/client_menu.c
openbox/config.c
openbox/event.c
openbox/keyboard.c
openbox/menu.c
openbox/menu.h
openbox/menuframe.c
openbox/menuframe.h
openbox/misc.h
openbox/mouse.c
openbox/mouse.h

index 0a7bee06bbd8978f4f6f46d718d7defc9e9d714f..d658f279b30850627e428149ed09c11762f211a4 100644 (file)
     <action name="PreviousWindow"/>
   </keybind>
   <keybind key="A-F7">
-    <action name="KeyboardMove"/>
+    <action name="Move"/>
   </keybind>
   <keybind key="A-F8">
-    <action name="KeyboardResize"/>
+    <action name="Resize"/>
   </keybind>
   <keybind key="A-F9">
     <action name="Iconify"/>
index fcbf683a671fce5196366c475e17766550c3ae15..e0f411e0fa2a1b47ca1dc211c072f69a20224acc 100644 (file)
@@ -5,21 +5,22 @@
 #include "menu.h"
 #include "prop.h"
 #include "stacking.h"
-#include "frame.h"
 #include "screen.h"
 #include "action.h"
 #include "openbox.h"
 #include "grab.h"
+#include "keyboard.h"
 
 #include <glib.h>
 
 typedef struct ActionString {
     char *name;
     void (*func)(union ActionData *);
-    void (*setup)(ObAction *);
+    void (*setup)(ObAction **, ObUserAction uact);
 } ActionString;
 
-ObAction *action_new(void (*func)(union ActionData *data))
+static ObAction *action_new(void (*func)(union ActionData *data),
+                            ObUserAction uact)
 {
     ObAction *a = g_new0(ObAction, 1);
     a->func = func;
@@ -40,262 +41,255 @@ void action_free(ObAction *a)
     g_free(a);
 }
 
-void setup_action_directional_focus_north(ObAction *a)
+void setup_action_directional_focus_north(ObAction **a, ObUserAction uact)
 { 
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_NORTH;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_NORTH;
 }
 
-void setup_action_directional_focus_east(ObAction *a)
+void setup_action_directional_focus_east(ObAction **a, ObUserAction uact)
 {
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_EAST;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_EAST;
 }
 
-void setup_action_directional_focus_south(ObAction *a)
+void setup_action_directional_focus_south(ObAction **a, ObUserAction uact)
 {
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_SOUTH;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_SOUTH;
 }
 
-void setup_action_directional_focus_west(ObAction *a)
+void setup_action_directional_focus_west(ObAction **a, ObUserAction uact)
 {
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_WEST;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_WEST;
 }
 
-void setup_action_directional_focus_northeast(ObAction *a)
+void setup_action_directional_focus_northeast(ObAction **a, ObUserAction uact)
 {
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_NORTHEAST;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_NORTHEAST;
 }
 
-void setup_action_directional_focus_southeast(ObAction *a)
+void setup_action_directional_focus_southeast(ObAction **a, ObUserAction uact)
 {
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_SOUTHEAST;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHEAST;
 }
 
-void setup_action_directional_focus_southwest(ObAction *a)
+void setup_action_directional_focus_southwest(ObAction **a, ObUserAction uact)
 {
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_SOUTHWEST;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_SOUTHWEST;
 }
 
-void setup_action_directional_focus_northwest(ObAction *a)
+void setup_action_directional_focus_northwest(ObAction **a, ObUserAction uact)
 {
-    a->data.interdiraction.inter.any.interactive = TRUE;
-    a->data.interdiraction.direction = OB_DIRECTION_NORTHWEST;
+    (*a)->data.interdiraction.inter.any.interactive = TRUE;
+    (*a)->data.interdiraction.direction = OB_DIRECTION_NORTHWEST;
 }
 
-void setup_action_send_to_desktop(ObAction *a)
+void setup_action_send_to_desktop(ObAction **a, ObUserAction uact)
 {
-    a->data.sendto.follow = TRUE;
+    (*a)->data.sendto.follow = TRUE;
 }
 
-void setup_action_send_to_desktop_prev(ObAction *a)
+void setup_action_send_to_desktop_prev(ObAction **a, ObUserAction uact)
 {
-    a->data.sendtodir.inter.any.interactive = TRUE;
-    a->data.sendtodir.dir = OB_DIRECTION_WEST;
-    a->data.sendtodir.linear = TRUE;
-    a->data.sendtodir.wrap = TRUE;
-    a->data.sendtodir.follow = TRUE;
+    (*a)->data.sendtodir.inter.any.interactive = TRUE;
+    (*a)->data.sendtodir.dir = OB_DIRECTION_WEST;
+    (*a)->data.sendtodir.linear = TRUE;
+    (*a)->data.sendtodir.wrap = TRUE;
+    (*a)->data.sendtodir.follow = TRUE;
 }
 
-void setup_action_send_to_desktop_next(ObAction *a)
+void setup_action_send_to_desktop_next(ObAction **a, ObUserAction uact)
 {
-    a->data.sendtodir.inter.any.interactive = TRUE;
-    a->data.sendtodir.dir = OB_DIRECTION_EAST;
-    a->data.sendtodir.linear = TRUE;
-    a->data.sendtodir.wrap = TRUE;
-    a->data.sendtodir.follow = TRUE;
+    (*a)->data.sendtodir.inter.any.interactive = TRUE;
+    (*a)->data.sendtodir.dir = OB_DIRECTION_EAST;
+    (*a)->data.sendtodir.linear = TRUE;
+    (*a)->data.sendtodir.wrap = TRUE;
+    (*a)->data.sendtodir.follow = TRUE;
 }
 
-void setup_action_send_to_desktop_left(ObAction *a)
+void setup_action_send_to_desktop_left(ObAction **a, ObUserAction uact)
 {
-    a->data.sendtodir.inter.any.interactive = TRUE;
-    a->data.sendtodir.dir = OB_DIRECTION_WEST;
-    a->data.sendtodir.linear = FALSE;
-    a->data.sendtodir.wrap = TRUE;
-    a->data.sendtodir.follow = TRUE;
+    (*a)->data.sendtodir.inter.any.interactive = TRUE;
+    (*a)->data.sendtodir.dir = OB_DIRECTION_WEST;
+    (*a)->data.sendtodir.linear = FALSE;
+    (*a)->data.sendtodir.wrap = TRUE;
+    (*a)->data.sendtodir.follow = TRUE;
 }
 
-void setup_action_send_to_desktop_right(ObAction *a)
+void setup_action_send_to_desktop_right(ObAction **a, ObUserAction uact)
 {
-    a->data.sendtodir.inter.any.interactive = TRUE;
-    a->data.sendtodir.dir = OB_DIRECTION_EAST;
-    a->data.sendtodir.linear = FALSE;
-    a->data.sendtodir.wrap = TRUE;
-    a->data.sendtodir.follow = TRUE;
+    (*a)->data.sendtodir.inter.any.interactive = TRUE;
+    (*a)->data.sendtodir.dir = OB_DIRECTION_EAST;
+    (*a)->data.sendtodir.linear = FALSE;
+    (*a)->data.sendtodir.wrap = TRUE;
+    (*a)->data.sendtodir.follow = TRUE;
 }
 
-void setup_action_send_to_desktop_up(ObAction *a)
+void setup_action_send_to_desktop_up(ObAction **a, ObUserAction uact)
 {
-    a->data.sendtodir.inter.any.interactive = TRUE;
-    a->data.sendtodir.dir = OB_DIRECTION_NORTH;
-    a->data.sendtodir.linear = FALSE;
-    a->data.sendtodir.wrap = TRUE;
-    a->data.sendtodir.follow = TRUE;
+    (*a)->data.sendtodir.inter.any.interactive = TRUE;
+    (*a)->data.sendtodir.dir = OB_DIRECTION_NORTH;
+    (*a)->data.sendtodir.linear = FALSE;
+    (*a)->data.sendtodir.wrap = TRUE;
+    (*a)->data.sendtodir.follow = TRUE;
 }
 
-void setup_action_send_to_desktop_down(ObAction *a)
+void setup_action_send_to_desktop_down(ObAction **a, ObUserAction uact)
 {
-    a->data.sendtodir.inter.any.interactive = TRUE;
-    a->data.sendtodir.dir = OB_DIRECTION_SOUTH;
-    a->data.sendtodir.linear = FALSE;
-    a->data.sendtodir.wrap = TRUE;
-    a->data.sendtodir.follow = TRUE;
+    (*a)->data.sendtodir.inter.any.interactive = TRUE;
+    (*a)->data.sendtodir.dir = OB_DIRECTION_SOUTH;
+    (*a)->data.sendtodir.linear = FALSE;
+    (*a)->data.sendtodir.wrap = TRUE;
+    (*a)->data.sendtodir.follow = TRUE;
 }
 
-void setup_action_desktop_prev(ObAction *a)
+void setup_action_desktop_prev(ObAction **a, ObUserAction uact)
 {
-    a->data.desktopdir.inter.any.interactive = TRUE;
-    a->data.desktopdir.dir = OB_DIRECTION_WEST;
-    a->data.desktopdir.linear = TRUE;
-    a->data.desktopdir.wrap = TRUE;
+    (*a)->data.desktopdir.inter.any.interactive = TRUE;
+    (*a)->data.desktopdir.dir = OB_DIRECTION_WEST;
+    (*a)->data.desktopdir.linear = TRUE;
+    (*a)->data.desktopdir.wrap = TRUE;
 }
 
-void setup_action_desktop_next(ObAction *a)
+void setup_action_desktop_next(ObAction **a, ObUserAction uact)
 {
-    a->data.desktopdir.inter.any.interactive = TRUE;
-    a->data.desktopdir.dir = OB_DIRECTION_EAST;
-    a->data.desktopdir.linear = TRUE;
-    a->data.desktopdir.wrap = TRUE;
+    (*a)->data.desktopdir.inter.any.interactive = TRUE;
+    (*a)->data.desktopdir.dir = OB_DIRECTION_EAST;
+    (*a)->data.desktopdir.linear = TRUE;
+    (*a)->data.desktopdir.wrap = TRUE;
 }
 
-void setup_action_desktop_left(ObAction *a)
+void setup_action_desktop_left(ObAction **a, ObUserAction uact)
 {
-    a->data.desktopdir.inter.any.interactive = TRUE;
-    a->data.desktopdir.dir = OB_DIRECTION_WEST;
-    a->data.desktopdir.linear = FALSE;
-    a->data.desktopdir.wrap = TRUE;
+    (*a)->data.desktopdir.inter.any.interactive = TRUE;
+    (*a)->data.desktopdir.dir = OB_DIRECTION_WEST;
+    (*a)->data.desktopdir.linear = FALSE;
+    (*a)->data.desktopdir.wrap = TRUE;
 }
 
-void setup_action_desktop_right(ObAction *a)
+void setup_action_desktop_right(ObAction **a, ObUserAction uact)
 {
-    a->data.desktopdir.inter.any.interactive = TRUE;
-    a->data.desktopdir.dir = OB_DIRECTION_EAST;
-    a->data.desktopdir.linear = FALSE;
-    a->data.desktopdir.wrap = TRUE;
+    (*a)->data.desktopdir.inter.any.interactive = TRUE;
+    (*a)->data.desktopdir.dir = OB_DIRECTION_EAST;
+    (*a)->data.desktopdir.linear = FALSE;
+    (*a)->data.desktopdir.wrap = TRUE;
 }
 
-void setup_action_desktop_up(ObAction *a)
+void setup_action_desktop_up(ObAction **a, ObUserAction uact)
 {
-    a->data.desktopdir.inter.any.interactive = TRUE;
-    a->data.desktopdir.dir = OB_DIRECTION_NORTH;
-    a->data.desktopdir.linear = FALSE;
-    a->data.desktopdir.wrap = TRUE;
+    (*a)->data.desktopdir.inter.any.interactive = TRUE;
+    (*a)->data.desktopdir.dir = OB_DIRECTION_NORTH;
+    (*a)->data.desktopdir.linear = FALSE;
+    (*a)->data.desktopdir.wrap = TRUE;
 }
 
-void setup_action_desktop_down(ObAction *a)
+void setup_action_desktop_down(ObAction **a, ObUserAction uact)
 {
-    a->data.desktopdir.inter.any.interactive = TRUE;
-    a->data.desktopdir.dir = OB_DIRECTION_SOUTH;
-    a->data.desktopdir.linear = FALSE;
-    a->data.desktopdir.wrap = TRUE;
+    (*a)->data.desktopdir.inter.any.interactive = TRUE;
+    (*a)->data.desktopdir.dir = OB_DIRECTION_SOUTH;
+    (*a)->data.desktopdir.linear = FALSE;
+    (*a)->data.desktopdir.wrap = TRUE;
 }
 
-void setup_action_move_keyboard(ObAction *a)
+void setup_action_cycle_windows_next(ObAction **a, ObUserAction uact)
 {
-    a->data.moveresize.corner = prop_atoms.net_wm_moveresize_move_keyboard;
+    (*a)->data.cycle.inter.any.interactive = TRUE;
+    (*a)->data.cycle.linear = FALSE;
+    (*a)->data.cycle.forward = TRUE;
 }
 
-void setup_action_move(ObAction *a)
+void setup_action_cycle_windows_previous(ObAction **a, ObUserAction uact)
 {
-    a->data.moveresize.corner = prop_atoms.net_wm_moveresize_move;
+    (*a)->data.cycle.inter.any.interactive = TRUE;
+    (*a)->data.cycle.linear = FALSE;
+    (*a)->data.cycle.forward = FALSE;
 }
 
-void setup_action_resize(ObAction *a)
+void setup_action_movetoedge_north(ObAction **a, ObUserAction uact)
 {
-    a->data.moveresize.corner = prop_atoms.net_wm_moveresize_size_topleft;
+    (*a)->data.diraction.direction = OB_DIRECTION_NORTH;
 }
 
-void setup_action_resize_keyboard(ObAction *a)
+void setup_action_movetoedge_south(ObAction **a, ObUserAction uact)
 {
-    a->data.moveresize.corner = prop_atoms.net_wm_moveresize_size_keyboard;
+    (*a)->data.diraction.direction = OB_DIRECTION_SOUTH;
 }
 
-void setup_action_cycle_windows_linear_next(ObAction *a)
+void setup_action_movetoedge_east(ObAction **a, ObUserAction uact)
 {
-    a->data.cycle.inter.any.interactive = TRUE;
-    a->data.cycle.linear = TRUE;
-    a->data.cycle.forward = TRUE;
+    (*a)->data.diraction.direction = OB_DIRECTION_EAST;
 }
 
-void setup_action_cycle_windows_linear_previous(ObAction *a)
+void setup_action_movetoedge_west(ObAction **a, ObUserAction uact)
 {
-    a->data.cycle.inter.any.interactive = TRUE;
-    a->data.cycle.linear = TRUE;
-    a->data.cycle.forward = FALSE;
+    (*a)->data.diraction.direction = OB_DIRECTION_WEST;
 }
 
-void setup_action_cycle_windows_next(ObAction *a)
+void setup_action_growtoedge_north(ObAction **a, ObUserAction uact)
 {
-    a->data.cycle.inter.any.interactive = TRUE;
-    a->data.cycle.linear = FALSE;
-    a->data.cycle.forward = TRUE;
+    (*a)->data.diraction.direction = OB_DIRECTION_NORTH;
 }
 
-void setup_action_cycle_windows_previous(ObAction *a)
+void setup_action_growtoedge_south(ObAction **a, ObUserAction uact)
 {
-    a->data.cycle.inter.any.interactive = TRUE;
-    a->data.cycle.linear = FALSE;
-    a->data.cycle.forward = FALSE;
+    (*a)->data.diraction.direction = OB_DIRECTION_SOUTH;
 }
 
-void setup_action_movetoedge_north(ObAction *a)
+void setup_action_growtoedge_east(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_NORTH;
+    (*a)->data.diraction.direction = OB_DIRECTION_EAST;
 }
 
-void setup_action_movetoedge_south(ObAction *a)
+void setup_action_growtoedge_west(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_SOUTH;
+    (*a)->data.diraction.direction = OB_DIRECTION_WEST;
 }
 
-void setup_action_movetoedge_east(ObAction *a)
+void setup_action_top_layer(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_EAST;
+    (*a)->data.layer.layer = 1;
 }
 
-void setup_action_movetoedge_west(ObAction *a)
+void setup_action_normal_layer(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_WEST;
+    (*a)->data.layer.layer = 0;
 }
 
-void setup_action_growtoedge_north(ObAction *a)
+void setup_action_bottom_layer(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_NORTH;
+    (*a)->data.layer.layer = -1;
 }
 
-void setup_action_growtoedge_south(ObAction *a)
+void setup_action_move(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_SOUTH;
+    (*a)->data.moveresize.move = TRUE;
+    (*a)->data.moveresize.keyboard =
+        (uact == OB_USER_ACTION_KEYBOARD_KEY ||
+         uact == OB_USER_ACTION_MENU_SELECTION);
 }
 
-void setup_action_growtoedge_east(ObAction *a)
+void setup_action_resize(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_EAST;
+    (*a)->data.moveresize.move = FALSE;
+    (*a)->data.moveresize.keyboard =
+        (uact == OB_USER_ACTION_KEYBOARD_KEY ||
+         uact == OB_USER_ACTION_MENU_SELECTION);
 }
 
-void setup_action_growtoedge_west(ObAction *a)
+void setup_action_showmenu(ObAction **a, ObUserAction uact)
 {
-    a->data.diraction.direction = OB_DIRECTION_WEST;
-}
-
-void setup_action_top_layer(ObAction *a)
-{
-    a->data.layer.layer = 1;
-}
-
-void setup_action_normal_layer(ObAction *a)
-{
-    a->data.layer.layer = 0;
-}
-
-void setup_action_bottom_layer(ObAction *a)
-{
-    a->data.layer.layer = -1;
+    /* you cannot call ShowMenu from inside a menu, cuz the menu code makes
+       assumptions that there is only one menu (and submenus) open at
+       a time! */
+    if (uact == OB_USER_ACTION_MENU_SELECTION) {
+        action_free(*a);
+        a = NULL;
+    }
 }
 
 ActionString actionstrings[] =
@@ -348,12 +342,12 @@ ActionString actionstrings[] =
     {
         "activate",
         action_activate,
-        NULL,
+        NULL
     },
     {
         "focus",
         action_focus,
-        NULL,
+        NULL
     },
     {
         "unfocus",
@@ -560,11 +554,6 @@ ActionString actionstrings[] =
         action_toggle_decorations,
         NULL
     },
-    {
-        "keyboardmove", 
-        action_moveresize,
-        setup_action_move_keyboard
-    },
     {
         "move",
         action_moveresize,
@@ -575,11 +564,6 @@ ActionString actionstrings[] =
         action_moveresize,
         setup_action_resize
     },
-    {
-        "keyboardresize",
-        action_moveresize,
-        setup_action_resize_keyboard
-    },
     {
         "toggleshowdesktop",
         action_toggle_show_desktop,
@@ -618,7 +602,7 @@ ActionString actionstrings[] =
     {
         "showmenu",
         action_showmenu,
-        NULL
+        setup_action_showmenu
     },
     {
         "sendtotoplayer",
@@ -645,16 +629,6 @@ ActionString actionstrings[] =
         action_toggle_layer,
         setup_action_bottom_layer
     },
-    {
-        "nextwindowlinear",
-        action_cycle_windows,
-        setup_action_cycle_windows_linear_next
-    },
-    {
-        "previouswindowlinear",
-        action_cycle_windows,
-        setup_action_cycle_windows_linear_previous
-    },
     {
         "nextwindow",
         action_cycle_windows,
@@ -712,32 +686,37 @@ ActionString actionstrings[] =
     }
 };
 
-ObAction *action_from_string(char *name)
+ObAction *action_from_string(char *name, ObUserAction uact)
 {
     ObAction *a = NULL;
+    gboolean exist = FALSE;
     int i;
 
     for (i = 0; actionstrings[i].name; i++)
         if (!g_ascii_strcasecmp(name, actionstrings[i].name)) {
-            a = action_new(actionstrings[i].func);
+            exist = TRUE;
+            a = action_new(actionstrings[i].func, uact);
             if (actionstrings[i].setup)
-                actionstrings[i].setup(a);
+                actionstrings[i].setup(&a, uact);
             break;
         }
-    if (!a)
+    if (!exist)
         g_warning("Invalid action '%s' requested. No such action exists.",
                   name);
+    if (!a)
+        g_warning("Invalid use of action '%s'. Action will be ignored.", name);
     return a;
 }
 
-ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
+                       ObUserAction uact)
 {
     char *actname;
     ObAction *act = NULL;
     xmlNodePtr n;
 
     if (parse_attr_string("name", node, &actname)) {
-        if ((act = action_from_string(actname))) {
+        if ((act = action_from_string(actname, uact))) {
             if (act->func == action_execute || act->func == action_restart) {
                 if ((n = parse_find_node("execute", node->xmlChildrenNode))) {
                     gchar *s = parse_string(doc, n);
@@ -747,26 +726,25 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
             } else if (act->func == action_showmenu) {
                 if ((n = parse_find_node("menu", node->xmlChildrenNode)))
                     act->data.showmenu.name = parse_string(doc, n);
+            } else if (act->func == action_move_relative_horz ||
+                       act->func == action_move_relative_vert ||
+                       act->func == action_resize_relative_horz ||
+                       act->func == action_resize_relative_vert) {
+                if ((n = parse_find_node("delta", node->xmlChildrenNode)))
+                    act->data.relative.delta = parse_int(doc, n);
             } else if (act->func == action_desktop) {
                 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
                     act->data.desktop.desk = parse_int(doc, n);
                 if (act->data.desktop.desk > 0) act->data.desktop.desk--;
-            } else if (act->func == action_send_to_desktop) {
+           } else if (act->func == action_send_to_desktop) {
                 if ((n = parse_find_node("desktop", node->xmlChildrenNode)))
                     act->data.sendto.desk = parse_int(doc, n);
                 if (act->data.sendto.desk > 0) act->data.sendto.desk--;
-            } else if (act->func == action_move_relative_horz ||
-                       act->func == action_move_relative_vert ||
-                       act->func == action_resize_relative_horz ||
-                       act->func == action_resize_relative_vert) {
-                if ((n = parse_find_node("delta", node->xmlChildrenNode)))
-                    act->data.relative.delta = parse_int(doc, n);
-            } else if (act->func == action_desktop_dir) {
-                if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
-                    act->data.desktopdir.wrap = parse_bool(doc, n);
-            } else if (act->func == action_send_to_desktop) {
                 if ((n = parse_find_node("follow", node->xmlChildrenNode)))
                     act->data.sendto.follow = parse_bool(doc, n);
+            } else if (act->func == action_desktop_dir) {
+                if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
+                    act->data.desktopdir.wrap = parse_bool(doc, n); 
             } else if (act->func == action_send_to_desktop_dir) {
                 if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
                     act->data.sendtodir.wrap = parse_bool(doc, n);
@@ -775,6 +753,9 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
             } else if (act->func == action_activate) {
                 if ((n = parse_find_node("here", node->xmlChildrenNode)))
                     act->data.activate.here = parse_bool(doc, n);
+            } else if (act->func == action_cycle_windows) {
+                if ((n = parse_find_node("linear", node->xmlChildrenNode)))
+                    act->data.cycle.linear = parse_bool(doc, n);
             }
         }
         g_free(actname);
@@ -782,6 +763,30 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
     return act;
 }
 
+void action_run_full(ObAction *a, struct _ObClient *c,
+                     ObFrameContext context,
+                     guint state, guint button, gint x, gint y,
+                     gboolean cancel, gboolean done)
+{
+    if (x < 0 && y < 0)
+        screen_pointer_pos(&x, &y);
+
+    a->data.any.c = c;
+    a->data.any.x = x;
+    a->data.any.y = y;
+
+    a->data.any.button = button;
+
+    if (a->data.any.interactive) {
+        a->data.inter.cancel = cancel;
+        a->data.inter.final = done;
+        if (!(cancel || done))
+            keyboard_interactive_grab(state, c, context, a);
+    }
+
+    a->func(&a->data);
+}
+
 void action_execute(union ActionData *data)
 {
     GError *e = NULL;
@@ -1089,14 +1094,48 @@ void action_toggle_decorations(union ActionData *data)
     client_setup_decor_and_functions(c);
 }
 
+static guint32 pick_corner(int x, int y, int cx, int cy, int cw, int ch)
+{
+    if (x - cx > cw / 2) {
+        if (y - cy > ch / 2)
+            return prop_atoms.net_wm_moveresize_size_bottomright;
+        else
+            return prop_atoms.net_wm_moveresize_size_topright;
+    } else {
+        if (y - cy > ch / 2)
+            return prop_atoms.net_wm_moveresize_size_bottomleft;
+        else
+            return prop_atoms.net_wm_moveresize_size_topleft;
+    }
+}
+
 void action_moveresize(union ActionData *data)
 {
     ObClient *c = data->moveresize.any.c;
+    guint32 corner;
 
     if (!c || !client_normal(c)) return;
 
-    moveresize_start(c, data->moveresize.x, data->moveresize.y,
-                     data->moveresize.button, data->moveresize.corner);
+    if (data->moveresize.keyboard) {
+        corner = (data->moveresize.move ?
+                  prop_atoms.net_wm_moveresize_move_keyboard :
+                  prop_atoms.net_wm_moveresize_size_keyboard);
+    } else {
+        corner = (data->moveresize.move ?
+                  prop_atoms.net_wm_moveresize_move :
+                  pick_corner(data->any.x, data->any.y,
+                              c->frame->area.x, c->frame->area.y,
+                              /* use the client size because the frame
+                                 can be differently sized (shaded
+                                 windows) and we want this based on the
+                                 clients size */
+                              c->area.width + c->frame->size.left +
+                              c->frame->size.right,
+                              c->area.height + c->frame->size.top +
+                              c->frame->size.bottom));
+    }
+
+    moveresize_start(c, data->any.x, data->any.y, data->any.button, corner);
 }
 
 void action_reconfigure(union ActionData *data)
@@ -1117,7 +1156,7 @@ void action_exit(union ActionData *data)
 void action_showmenu(union ActionData *data)
 {
     if (data->showmenu.name) {
-        menu_show(data->showmenu.name, data->showmenu.x, data->showmenu.y,
+        menu_show(data->showmenu.name, data->any.x, data->any.y,
                   data->showmenu.any.c);
     }
 }
index 99ba93158618f233d40239f76d97b1ba706d9571..18525072b2755a8a05b4284002c690fd46b642bf 100644 (file)
@@ -2,8 +2,11 @@
 #define __action_h
 
 #include "misc.h"
+#include "frame.h"
 #include "parser/parse.h"
 
+struct _ObClient;
+
 typedef struct _ObAction ObAction;
 
 /* These have to all have a Client* at the top even if they don't use it, so
@@ -14,6 +17,9 @@ typedef struct _ObAction ObAction;
 struct AnyAction {
     struct _ObClient *c;
     gboolean interactive;
+    gint x;
+    gint y;
+    gint button;
 };
 
 struct InteractiveAction {
@@ -84,17 +90,13 @@ struct DesktopDirection {
 
 struct MoveResize {
     struct AnyAction any;
-    int x;
-    int y;
-    guint32 corner; /* prop_atoms.net_wm_moveresize_* */
-    guint button;
+    gboolean move;
+    gboolean keyboard;
 };
 
 struct ShowMenu {
     struct AnyAction any;
     char *name;
-    int x;
-    int y;
 };
 
 struct CycleWindows {
@@ -123,6 +125,7 @@ union ActionData {
 };
 
 struct _ObAction {
+    ObUserAction act;
     /* The func member acts like an enum to tell which one of the structs in
        the data union are valid.
     */
@@ -130,24 +133,53 @@ struct _ObAction {
     union ActionData data;
 };
 
-ObAction *action_new(void (*func)(union ActionData *data));
-
 /* Creates a new Action from the name of the action
    A few action types need data set after making this call still. Check if
    the returned action's "func" is one of these.
    action_execute - the path needs to be set
    action_restart - the path can optionally be set
    action_desktop - the destination desktop needs to be set
+   action_send_to_desktop - the destination desktop needs to be set
    action_move_relative_horz - the delta
    action_move_relative_vert - the delta
    action_resize_relative_horz - the delta
    action_resize_relative_vert - the delta
 */
 
-ObAction *action_from_string(char *name);
-ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+ObAction *action_from_string(char *name, ObUserAction uact);
+ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
+                       ObUserAction uact);
 void action_free(ObAction *a);
 
+/*! Executes an action.
+  @param c The client associated with the action. Can be NULL.
+  @param context The context in which the user action occured.
+  @param state The keyboard modifiers state at the time the user action occured
+  @param button The mouse button used to execute the action.
+  @param x The x coord at which the user action occured.
+  @param y The y coord at which the user action occured.
+  @param cancel If the action is cancelling an interactive action. This only
+         affects interactive actions, but should generally always be FALSE.
+  @param done If the action is completing an interactive action. This only
+         affects interactive actions, but should generally always be FALSE.
+*/
+void action_run_full(ObAction *a, struct _ObClient *c,
+                     ObFrameContext context,
+                     guint state, guint button, gint x, gint y,
+                     gboolean cancel, gboolean done);
+
+#define action_run_mouse(a, c, t, s, b, x, y) \
+    action_run_full(a, c, t, s, b, x, y, FALSE, FALSE)
+
+#define action_run_interactive(a, c, s, n, d) \
+    action_run_full(a, c, OB_FRAME_CONTEXT_NONE, s, 0, -1, -1, n, d)
+
+#define action_run_key(a, c, s, x, y) \
+    action_run_full(a, c, OB_FRAME_CONTEXT_NONE, s, 0, x, y, FALSE,FALSE)
+
+#define action_run(a, c, s) \
+    action_run_full(a, c, OB_FRAME_CONTEXT_NONE, s, 0, -1, -1, FALSE,FALSE)
+
 /* Execute */
 void action_execute(union ActionData *data);
 /* ActivateAction */
index 2dab84fc32c38991b5226fddd07d31132fcaf500..9b904f4dc6fe6c184d926a5c772e160206812548 100644 (file)
@@ -40,7 +40,8 @@ static void desk_menu_update(ObMenuFrame *frame, gpointer data)
                 menu_add_separator(menu, -1);
             }
 
-            act = action_from_string("activate");
+            act = action_from_string("Activate",
+                                     OB_USER_ACTION_MENU_SELECTION);
             act->data.activate.any.c = c;
             acts = g_slist_prepend(NULL, act);
             e = menu_add_normal(menu, i,
@@ -56,16 +57,16 @@ static void desk_menu_update(ObMenuFrame *frame, gpointer data)
     
 }
 
-/* executes it without changing the client in the actions, since we set that
+/* executes it using the client in the actions, since we set that
    when we make the actions! */
-static void desk_menu_execute(ObMenuEntry *self, gpointer data)
+static void desk_menu_execute(ObMenuEntry *self, guint state, gpointer data)
 {
     GSList *it;
 
     for (it = self->data.normal.actions; it; it = g_slist_next(it))
     {
         ObAction *act = it->data;
-        act->func(&act->data);
+        action_run(it->data, act->data.any.c, state);
     }
 }
 
index dc724383e4319366f530f7d426d15be47cb0a546..5a4dbc72f11915fa26331f8a7a503655f08d4718 100644 (file)
@@ -120,7 +120,8 @@ static void send_to_update(ObMenuFrame *frame, gpointer data)
             name = screen_desktop_names[i];
         }
 
-        act = action_from_string("SendToDesktop");
+        act = action_from_string("SendToDesktop",
+                                 OB_USER_ACTION_MENU_SELECTION);
         act->data.sendto.desk = desk;
         act->data.sendto.follow = FALSE;
         acts = g_slist_prepend(NULL, act);
@@ -143,13 +144,18 @@ void client_menu_startup()
     menu = menu_new(LAYER_MENU_NAME, _("Layer"), NULL);
     menu_set_update_func(menu, layer_update);
 
-    acts = g_slist_prepend(NULL, action_from_string("SendToTopLayer"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("SendToTopLayer", OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, LAYER_TOP, _("Always on top"), acts);
 
-    acts = g_slist_prepend(NULL, action_from_string("SendToNormalLayer"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("SendToNormalLayer",
+                            OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, LAYER_NORMAL, _("Normal"), acts);
 
-    acts = g_slist_prepend(NULL, action_from_string("SendToBottomLayer"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("SendToBottomLayer",
+                            OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, LAYER_BOTTOM, _("Always on bottom"),acts);
 
 
@@ -168,47 +174,58 @@ void client_menu_startup()
 
     menu_add_submenu(menu, CLIENT_LAYER, LAYER_MENU_NAME);
 
-    acts = g_slist_prepend(NULL, action_from_string("Iconify"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("Iconify", OB_USER_ACTION_MENU_SELECTION));
     e = menu_add_normal(menu, CLIENT_ICONIFY, _("Iconify"), acts);
     e->data.normal.mask = ob_rr_theme->iconify_mask;
     e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
     e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color;
     e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color;
 
-    acts = g_slist_prepend(NULL, action_from_string("ToggleMaximizeFull"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("ToggleMaximizeFull",
+                            OB_USER_ACTION_MENU_SELECTION));
     e = menu_add_normal(menu, CLIENT_MAXIMIZE, _("Maximize"), acts);
     e->data.normal.mask = ob_rr_theme->max_mask; 
     e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
     e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color;
     e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color;
 
-    acts = g_slist_prepend(NULL, action_from_string("Raise"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("Raise", OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, CLIENT_RAISE, _("Raise to top"), acts);
 
-    acts = g_slist_prepend(NULL, action_from_string("Lower"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("Lower", OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, CLIENT_LOWER, _("Lower to bottom"),acts);
 
-    acts = g_slist_prepend(NULL, action_from_string("ToggleShade"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("ToggleShade", OB_USER_ACTION_MENU_SELECTION));
     e = menu_add_normal(menu, CLIENT_SHADE, _("Roll up/down"), acts);
     e->data.normal.mask = ob_rr_theme->shade_mask;
     e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
     e->data.normal.mask_disabled_color = ob_rr_theme->menu_disabled_color;
     e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_color;
 
-    acts = g_slist_prepend(NULL, action_from_string("ToggleDecorations"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("ToggleDecorations",
+                            OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, CLIENT_DECORATE, _("Decorate"), acts);
 
     menu_add_separator(menu, -1);
 
-    acts = g_slist_prepend(NULL, action_from_string("KeyboardMove"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("Move", OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, CLIENT_MOVE, _("Move"), acts);
 
-    acts = g_slist_prepend(NULL, action_from_string("KeyboardResize"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("Resize", OB_USER_ACTION_MENU_SELECTION));
     menu_add_normal(menu, CLIENT_RESIZE, _("Resize"), acts);
 
     menu_add_separator(menu, -1);
 
-    acts = g_slist_prepend(NULL, action_from_string("Close"));
+    acts = g_slist_prepend(NULL, action_from_string
+                           ("Close", OB_USER_ACTION_MENU_SELECTION));
     e = menu_add_normal(menu, CLIENT_CLOSE, _("Close"), acts);
     e->data.normal.mask = ob_rr_theme->close_mask;
     e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
index 7eaff1ae3bc22dda8fa539ad73d824c563bbe0cb..cee3c1378740a6c55b2e919ac245595af255dea0 100644 (file)
@@ -82,20 +82,9 @@ static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
     if (keylist) {
         nact = parse_find_node("action", node);
         while (nact) {
-            if ((action = action_parse(i, doc, nact))) {
-                /* validate that its okay for a key binding */
-                if (action->func == action_moveresize &&
-                    action->data.moveresize.corner !=
-                    prop_atoms.net_wm_moveresize_move_keyboard &&
-                    action->data.moveresize.corner !=
-                    prop_atoms.net_wm_moveresize_size_keyboard) {
-                    action_free(action);
-                    action = NULL;
-                }
-
-                if (action)
-                    keyboard_bind(keylist, action);
-            }
+            if ((action = action_parse(i, doc, nact,
+                                       OB_USER_ACTION_KEYBOARD_KEY)))
+                keyboard_bind(keylist, action);
             nact = parse_find_node("action", nact->next);
         }
     }
@@ -123,6 +112,7 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
     xmlNodePtr n, nbut, nact;
     char *buttonstr;
     char *contextstr;
+    ObUserAction uact;
     ObMouseAction mact;
     ObAction *action;
 
@@ -141,44 +131,27 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
         while (nbut) {
             if (!parse_attr_string("button", nbut, &buttonstr))
                 goto next_nbut;
-            if (parse_attr_contains("press", nbut, "action"))
+            if (parse_attr_contains("press", nbut, "action")) {
+                uact = OB_USER_ACTION_MOUSE_PRESS;
                 mact = OB_MOUSE_ACTION_PRESS;
-            else if (parse_attr_contains("release", nbut, "action"))
+            } else if (parse_attr_contains("release", nbut, "action")) {
+                uact = OB_USER_ACTION_MOUSE_RELEASE;
                 mact = OB_MOUSE_ACTION_RELEASE;
-            else if (parse_attr_contains("click", nbut, "action"))
+            } else if (parse_attr_contains("click", nbut, "action")) {
+                uact = OB_USER_ACTION_MOUSE_CLICK;
                 mact = OB_MOUSE_ACTION_CLICK;
-            else if (parse_attr_contains("doubleclick", nbut,"action"))
+            } else if (parse_attr_contains("doubleclick", nbut,"action")) {
+                uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK;
                 mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
-            else if (parse_attr_contains("drag", nbut, "action"))
+            } else if (parse_attr_contains("drag", nbut, "action")) {
+                uact = OB_USER_ACTION_MOUSE_MOTION;
                 mact = OB_MOUSE_ACTION_MOTION;
-            else
+            else
                 goto next_nbut;
             nact = parse_find_node("action", nbut->xmlChildrenNode);
             while (nact) {
-                if ((action = action_parse(i, doc, nact))) {
-                    /* validate that its okay for a mouse binding*/
-                    if (mact == OB_MOUSE_ACTION_MOTION) {
-                        if (action->func != action_moveresize ||
-                            action->data.moveresize.corner ==
-                            prop_atoms.net_wm_moveresize_move_keyboard ||
-                            action->data.moveresize.corner ==
-                            prop_atoms.net_wm_moveresize_size_keyboard) {
-                            action_free(action);
-                            action = NULL;
-                        }
-                    } else {
-                        if (action->func == action_moveresize &&
-                            action->data.moveresize.corner !=
-                            prop_atoms.net_wm_moveresize_move_keyboard &&
-                            action->data.moveresize.corner !=
-                            prop_atoms.net_wm_moveresize_size_keyboard) {
-                            action_free(action);
-                            action = NULL;
-                        }
-                    }
-                    if (action)
-                        mouse_bind(buttonstr, contextstr, mact, action);
-                }
+                if ((action = action_parse(i, doc, nact, uact)))
+                    mouse_bind(buttonstr, contextstr, mact, action);
                 nact = parse_find_node("action", nact->next);
             }
             g_free(buttonstr);
index e5f8d45ca5193281a9b8f7268d17fb934787c7cf..a9841b0e142f2c814035a579fc248b699a030dc2 100644 (file)
@@ -1126,8 +1126,7 @@ static void event_handle_menu(XEvent *ev)
         else {
             if ((e = menu_entry_frame_under(ev->xbutton.x_root,
                                             ev->xbutton.y_root)))
-                menu_entry_frame_execute(e,
-                                         !(ev->xbutton.state & ControlMask));
+                menu_entry_frame_execute(e, ev->xbutton.state);
         }
         break;
     case MotionNotify:
@@ -1145,8 +1144,7 @@ static void event_handle_menu(XEvent *ev)
         else if (ev->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
             ObMenuFrame *f;
             if ((f = find_active_menu()))
-                menu_entry_frame_execute(f->selected,
-                                         !(ev->xkey.state & ControlMask));
+                menu_entry_frame_execute(f->selected, ev->xkey.state);
         } else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) {
             ObMenuFrame *f;
             if ((f = find_active_menu()) && f->parent)
index cef0dfd68364179545010102d024c43a8b416e56..65d2f2e072f22a1891965a907b599ff2cb4445be 100644 (file)
@@ -133,6 +133,8 @@ void keyboard_interactive_grab(guint state, ObClient *client,
 {
     ObInteractiveState *s;
 
+    g_assert(action->data.any.interactive);
+
     if (!interactive_states) {
         if (!grab_keyboard(TRUE))
             return;
@@ -179,12 +181,8 @@ gboolean keyboard_process_interactive_grab(const XEvent *e,
                 cancel = done = TRUE;
         }
         if (done) {
-            g_assert(s->action->data.any.interactive);
-
-            s->action->data.inter.cancel = cancel;
-            s->action->data.inter.final = TRUE;
-
-            s->action->func(&s->action->data);
+            action_run_interactive(s->action, s->client,
+                                   e->xkey.state, cancel, TRUE);
 
             g_free(s);
 
@@ -221,7 +219,8 @@ void keyboard_event(ObClient *client, const XEvent *e)
         p = curpos->first_child;
     while (p) {
         if (p->key == e->xkey.keycode &&
-            p->state == e->xkey.state) {
+            p->state == e->xkey.state)
+        {
             if (p->first_child != NULL) { /* part of a chain */
                 ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
                 /* 5 second timeout for chains */
@@ -232,32 +231,10 @@ void keyboard_event(ObClient *client, const XEvent *e)
                 grab_keys(TRUE);
             } else {
                 GSList *it;
-                for (it = p->actions; it; it = it->next) {
-                    ObAction *act = it->data;
-                    if (act->func != NULL) {
-                        act->data.any.c = client;
-
-                        if (act->func == action_moveresize) {
-                            screen_pointer_pos(&act->data.moveresize.x,
-                                               &act->data.moveresize.y);
-                        }
-
-                        if (act->data.any.interactive) {
-                            act->data.inter.cancel = FALSE;
-                            act->data.inter.final = FALSE;
-                            keyboard_interactive_grab(e->xkey.state, client,
-                                                      0, act);
-                        }
-
-                        if (act->func == action_showmenu) {
-                            act->data.showmenu.x = e->xkey.x_root;
-                            act->data.showmenu.y = e->xkey.y_root;
-                        }
-
-                        act->data.any.c = client;
-                        act->func(&act->data);
-                    }
-                }
+
+                for (it = p->actions; it; it = it->next)
+                    action_run_key(it->data, client, e->xkey.state,
+                                   e->xkey.x_root, e->xkey.y_root);
 
                 keyboard_reset_chains();
             }
index 39e19246e297aadac6d37a5d02aea879a14d851a..74a743eed4bc4dbe0cb8e0ce17a81bf211ee04ac 100644 (file)
@@ -180,7 +180,9 @@ static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 
             for (node = node->xmlChildrenNode; node; node = node->next)
                 if (!xmlStrcasecmp(node->name, (const xmlChar*) "action"))
-                    acts = g_slist_append(acts, action_parse(i, doc, node));
+                    acts = g_slist_append(acts, action_parse
+                                          (i, doc, node,
+                                           OB_USER_ACTION_MENU_SELECTION));
             menu_add_normal(state->parent, -1, label, acts);
             g_free(label);
         }
index f6c334172c13cbb8c2ee0fa596f8316e52726c1a..5683cb2a292974559fc799986810de9cc680d070 100644 (file)
@@ -20,7 +20,8 @@ typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
 typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
 
 typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
-typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry, gpointer data);
+typedef void (*ObMenuExecuteFunc)(struct _ObMenuEntry *entry,
+                                  guint state, gpointer data);
 typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
 
 struct _ObMenu
index 7b758d30e281409a62a31bcc4353cad152d66d2b..f2a14e48835b8b7bb591b2575b02d603429254f5 100644 (file)
@@ -711,7 +711,7 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
     menu_frame_show(f, self->frame);
 }
 
-void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
+void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state)
 {
     if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
         self->entry->data.normal.enabled)
@@ -725,31 +725,16 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
         ObClient *client = self->frame->client;
 
         /* release grabs before executing the shit */
-        if (hide)
+        if (!(state & ControlMask))
             menu_frame_hide_all();
 
         if (func)
-            func(entry, data);
+            func(entry, state, data);
         else {
             GSList *it;
 
             for (it = acts; it; it = g_slist_next(it))
-            {
-                ObAction *act = it->data;
-                act->data.any.c = client;
-
-                if (act->func == action_moveresize)
-                    screen_pointer_pos(&act->data.moveresize.x,
-                                       &act->data.moveresize.y);
-
-                if (!(act->func == action_cycle_windows ||
-                      act->func == action_desktop_dir ||
-                      act->func == action_send_to_desktop_dir ||
-                      act->func == action_showmenu))
-                {
-                    act->func(&act->data);
-                }
-            }
+                action_run(it->data, client, state);
         }
     }
 }
index 34041149d3a09aa103d301f44933fe28c0ef7309..3a77ebf40f7ae56accd4bc0a0cadc3e3a38bc0ce 100644 (file)
@@ -100,6 +100,6 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y);
 
 void menu_entry_frame_show_submenu(ObMenuEntryFrame *self);
 
-void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide);
+void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state);
 
 #endif
index 24788c4fb03a03fda8790acda57e13e68fa9e914..f86c448419d05e00b2f66ca5be848859a4726e9a 100644 (file)
@@ -62,4 +62,24 @@ typedef enum
     OB_CORNER_BOTTOMRIGHT
 } ObCorner;
 
+typedef enum {
+    OB_MOUSE_ACTION_PRESS,
+    OB_MOUSE_ACTION_RELEASE,
+    OB_MOUSE_ACTION_CLICK,
+    OB_MOUSE_ACTION_DOUBLE_CLICK,
+    OB_MOUSE_ACTION_MOTION,
+    OB_NUM_MOUSE_ACTIONS
+} ObMouseAction;
+
+typedef enum {
+    OB_USER_ACTION_KEYBOARD_KEY,
+    OB_USER_ACTION_MOUSE_PRESS,
+    OB_USER_ACTION_MOUSE_RELEASE,
+    OB_USER_ACTION_MOUSE_CLICK,
+    OB_USER_ACTION_MOUSE_DOUBLE_CLICK,
+    OB_USER_ACTION_MOUSE_MOTION,
+    OB_USER_ACTION_MENU_SELECTION,
+    OB_NUM_USER_ACTIONS
+} ObUserAction;
+
 #endif
index 601c4f1bf5c16e3cdf84720c50b73a42c94c41b3..25068401362842542a6b9edbc49d295bab956c9a 100644 (file)
@@ -9,13 +9,12 @@
 #include "frame.h"
 #include "translate.h"
 #include "mouse.h"
-#include "keyboard.h"
 #include <glib.h>
 
 typedef struct {
     guint state;
     guint button;
-    GSList *actions[OB_MOUSE_NUM_ACTIONS]; /* lists of Action pointers */
+    GSList *actions[OB_NUM_MOUSE_ACTIONS]; /* lists of Action pointers */
 } ObMouseBinding;
 
 #define FRAME_CONTEXT(co, cl) ((cl && cl->type != OB_CLIENT_TYPE_DESKTOP) ? \
@@ -33,7 +32,7 @@ void mouse_grab_for_client(ObClient *client, gboolean grab)
     GSList *it;
 
     for (i = 0; i < OB_FRAME_NUM_CONTEXTS; ++i)
-        for (it = bound_contexts[i]; it != NULL; it = it->next) {
+        for (it = bound_contexts[i]; it != NULL; it = g_slist_next(it)) {
             /* grab/ungrab the button */
             ObMouseBinding *b = it->data;
             Window win;
@@ -75,14 +74,14 @@ static void clearall()
     
     for(i = 0; i < OB_FRAME_NUM_CONTEXTS; ++i) {
         for (it = bound_contexts[i]; it != NULL; it = it->next) {
+            ObMouseBinding *b = it->data;
             int j;
 
-            ObMouseBinding *b = it->data;
-            for (j = 0; j < OB_MOUSE_NUM_ACTIONS; ++j) {
+            for (j = 0; j < OB_NUM_MOUSE_ACTIONS; ++j) {
                 GSList *it;
-                for (it = b->actions[j]; it; it = it->next) {
+
+                for (it = b->actions[j]; it; it = it->next)
                     action_free(it->data);
-                }
                 g_slist_free(b->actions[j]);
             }
             g_free(b);
@@ -92,9 +91,9 @@ static void clearall()
     }
 }
 
-static gboolean fire_button(ObMouseAction a, ObFrameContext context,
-                            ObClient *c, guint state,
-                            guint button, int x, int y)
+static gboolean fire_binding(ObMouseAction a, ObFrameContext context,
+                             ObClient *c, guint state,
+                             guint button, int x, int y)
 {
     GSList *it;
     ObMouseBinding *b;
@@ -107,85 +106,11 @@ static gboolean fire_button(ObMouseAction a, ObFrameContext context,
     /* if not bound, then nothing to do! */
     if (it == NULL) return FALSE;
 
-    for (it = b->actions[a]; it; it = it->next) {
-        ObAction *act = it->data;
-        if (act->func != NULL) {
-            act->data.any.c = c;
-
-            g_assert(act->func != action_moveresize);
-
-            if (act->func == action_showmenu) {
-                act->data.showmenu.x = x;
-                act->data.showmenu.y = y;
-            }
-
-            if (act->data.any.interactive) {
-                act->data.inter.cancel = FALSE;
-                act->data.inter.final = FALSE;
-                keyboard_interactive_grab(state, c, context, act);
-            }
-
-            act->func(&act->data);
-        }
-    }
+    for (it = b->actions[a]; it; it = it->next)
+        action_run_mouse(it->data, c, context, state, button, x, y);
     return TRUE;
 }
 
-static gboolean fire_motion(ObMouseAction a, ObFrameContext context,
-                            ObClient *c, guint state, guint button,
-                            int x_root, int y_root, guint32 corner)
-{
-    GSList *it;
-    ObMouseBinding *b;
-
-    for (it = bound_contexts[context]; it != NULL; it = it->next) {
-        b = it->data;
-        if (b->state == state && b->button == button)
-               break;
-    }
-    /* if not bound, then nothing to do! */
-    if (it == NULL) return FALSE;
-
-    for (it = b->actions[a]; it; it = it->next) {
-        ObAction *act = it->data;
-        if (act->func != NULL) {
-            act->data.any.c = c;
-
-            if (act->func == action_moveresize) {
-                act->data.moveresize.x = x_root;
-                act->data.moveresize.y = y_root;
-                act->data.moveresize.button = button;
-                if (!(act->data.moveresize.corner ==
-                      prop_atoms.net_wm_moveresize_move ||
-                      act->data.moveresize.corner ==
-                      prop_atoms.net_wm_moveresize_move_keyboard ||
-                      act->data.moveresize.corner ==
-                      prop_atoms.net_wm_moveresize_size_keyboard))
-                    act->data.moveresize.corner = corner;
-            } else
-                g_assert_not_reached();
-
-            act->func(&act->data);
-        }
-    }
-    return TRUE;
-}
-
-static guint32 pick_corner(int x, int y, int cx, int cy, int cw, int ch)
-{
-    if (x - cx < cw / 2) {
-        if (y - cy < ch / 2)
-            return prop_atoms.net_wm_moveresize_size_topleft;
-        else
-            return prop_atoms.net_wm_moveresize_size_bottomleft;
-    } else {
-        if (y - cy < ch / 2)
-            return prop_atoms.net_wm_moveresize_size_topright;
-        else
-            return prop_atoms.net_wm_moveresize_size_bottomright;
-    }
-}
-
 void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
 {
     static Time ltime;
@@ -203,10 +128,10 @@ void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
         button = e->xbutton.button;
         state = e->xbutton.state;
 
-        fire_button(OB_MOUSE_ACTION_PRESS, context,
-                    client, e->xbutton.state,
-                    e->xbutton.button,
-                    e->xbutton.x_root, e->xbutton.y_root);
+        fire_binding(OB_MOUSE_ACTION_PRESS, context,
+                     client, e->xbutton.state,
+                     e->xbutton.button,
+                     e->xbutton.x_root, e->xbutton.y_root);
 
         if (CLIENT_CONTEXT(context, client)) {
             /* Replay the event, so it goes to the client*/
@@ -252,22 +177,22 @@ void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
             state = 0;
             ltime = e->xbutton.time;
         }
-        fire_button(OB_MOUSE_ACTION_RELEASE, context,
-                    client, e->xbutton.state,
-                    e->xbutton.button,
-                    e->xbutton.x_root, e->xbutton.y_root);
+        fire_binding(OB_MOUSE_ACTION_RELEASE, context,
+                     client, e->xbutton.state,
+                     e->xbutton.button,
+                     e->xbutton.x_root, e->xbutton.y_root);
         if (click)
-            fire_button(OB_MOUSE_ACTION_CLICK, context,
-                        client, e->xbutton.state,
-                        e->xbutton.button,
-                        e->xbutton.x_root,
-                        e->xbutton.y_root);
+            fire_binding(OB_MOUSE_ACTION_CLICK, context,
+                         client, e->xbutton.state,
+                         e->xbutton.button,
+                         e->xbutton.x_root,
+                         e->xbutton.y_root);
         if (dclick)
-            fire_button(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
-                        client, e->xbutton.state,
-                        e->xbutton.button,
-                        e->xbutton.x_root,
-                        e->xbutton.y_root);
+            fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
+                         client, e->xbutton.state,
+                         e->xbutton.button,
+                         e->xbutton.x_root,
+                         e->xbutton.y_root);
         break;
 
     case MotionNotify:
@@ -276,7 +201,6 @@ void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
                 config_mouse_threshold ||
                 ABS(e->xmotion.y_root - py) >=
                 config_mouse_threshold) {
-                guint32 corner;
 
                 /* You can't drag on buttons */
                 if (context == OB_FRAME_CONTEXT_MAXIMIZE ||
@@ -287,26 +211,8 @@ void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
                     context == OB_FRAME_CONTEXT_CLOSE)
                     break;
 
-                if (!client)
-                    corner = prop_atoms.net_wm_moveresize_size_bottomright;
-                else
-                    corner =
-                        pick_corner(e->xmotion.x_root,
-                                    e->xmotion.y_root,
-                                    client->frame->area.x,
-                                    client->frame->area.y,
-                                    /* use the client size because the frame
-                                       can be differently sized (shaded
-                                       windows) and we want this based on the
-                                       clients size */
-                                    client->area.width +
-                                    client->frame->size.left +
-                                    client->frame->size.right,
-                                    client->area.height +
-                                    client->frame->size.top +
-                                    client->frame->size.bottom);
-                fire_motion(OB_MOUSE_ACTION_MOTION, context,
-                            client, state, button, px, py, corner);
+                fire_binding(OB_MOUSE_ACTION_MOTION, context,
+                             client, state, button, px, py);
                 button = 0;
                 state = 0;
             }
index 4e68bf1abe9d882f5abd31bd08843f508e44921d..31ce40fed9098ee7c58f0b20d22fbb6c15f9f5a7 100644 (file)
@@ -3,18 +3,10 @@
 
 #include "action.h"
 #include "frame.h"
+#include "misc.h"
 
 #include <X11/Xlib.h>
 
-typedef enum {
-    OB_MOUSE_ACTION_PRESS,
-    OB_MOUSE_ACTION_RELEASE,
-    OB_MOUSE_ACTION_CLICK,
-    OB_MOUSE_ACTION_DOUBLE_CLICK,
-    OB_MOUSE_ACTION_MOTION,
-    OB_MOUSE_NUM_ACTIONS
-} ObMouseAction;
-
 void mouse_startup(gboolean reconfig);
 void mouse_shutdown(gboolean reconfig);
 
This page took 0.071657 seconds and 4 git commands to generate.