little bit of an actions overhaul, added action_run* so that duplicated code can all be in the same place now woot.
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
This commit is contained in:
parent
b23594d88d
commit
78282959f9
15 changed files with 402 additions and 459 deletions
|
@ -96,10 +96,10 @@
|
|||
<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"/>
|
||||
|
|
427
openbox/action.c
427
openbox/action.c
|
@ -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_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) {
|
||||
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) {
|
||||
} 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) {
|
||||
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--;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
156
openbox/mouse.c
156
openbox/mouse.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue