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"/>
|
<action name="PreviousWindow"/>
|
||||||
</keybind>
|
</keybind>
|
||||||
<keybind key="A-F7">
|
<keybind key="A-F7">
|
||||||
<action name="KeyboardMove"/>
|
<action name="Move"/>
|
||||||
</keybind>
|
</keybind>
|
||||||
<keybind key="A-F8">
|
<keybind key="A-F8">
|
||||||
<action name="KeyboardResize"/>
|
<action name="Resize"/>
|
||||||
</keybind>
|
</keybind>
|
||||||
<keybind key="A-F9">
|
<keybind key="A-F9">
|
||||||
<action name="Iconify"/>
|
<action name="Iconify"/>
|
||||||
|
|
425
openbox/action.c
425
openbox/action.c
|
@ -5,21 +5,22 @@
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "prop.h"
|
#include "prop.h"
|
||||||
#include "stacking.h"
|
#include "stacking.h"
|
||||||
#include "frame.h"
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
#include "openbox.h"
|
#include "openbox.h"
|
||||||
#include "grab.h"
|
#include "grab.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct ActionString {
|
typedef struct ActionString {
|
||||||
char *name;
|
char *name;
|
||||||
void (*func)(union ActionData *);
|
void (*func)(union ActionData *);
|
||||||
void (*setup)(ObAction *);
|
void (*setup)(ObAction **, ObUserAction uact);
|
||||||
} ActionString;
|
} 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);
|
ObAction *a = g_new0(ObAction, 1);
|
||||||
a->func = func;
|
a->func = func;
|
||||||
|
@ -40,262 +41,255 @@ void action_free(ObAction *a)
|
||||||
g_free(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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_NORTH;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_EAST;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_SOUTH;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_WEST;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_NORTHEAST;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_SOUTHEAST;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_SOUTHWEST;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.interdiraction.direction = OB_DIRECTION_NORTHWEST;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.sendtodir.dir = OB_DIRECTION_WEST;
|
(*a)->data.sendtodir.dir = OB_DIRECTION_WEST;
|
||||||
a->data.sendtodir.linear = TRUE;
|
(*a)->data.sendtodir.linear = TRUE;
|
||||||
a->data.sendtodir.wrap = TRUE;
|
(*a)->data.sendtodir.wrap = TRUE;
|
||||||
a->data.sendtodir.follow = 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.inter.any.interactive = TRUE;
|
||||||
a->data.sendtodir.dir = OB_DIRECTION_EAST;
|
(*a)->data.sendtodir.dir = OB_DIRECTION_EAST;
|
||||||
a->data.sendtodir.linear = TRUE;
|
(*a)->data.sendtodir.linear = TRUE;
|
||||||
a->data.sendtodir.wrap = TRUE;
|
(*a)->data.sendtodir.wrap = TRUE;
|
||||||
a->data.sendtodir.follow = 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.inter.any.interactive = TRUE;
|
||||||
a->data.sendtodir.dir = OB_DIRECTION_WEST;
|
(*a)->data.sendtodir.dir = OB_DIRECTION_WEST;
|
||||||
a->data.sendtodir.linear = FALSE;
|
(*a)->data.sendtodir.linear = FALSE;
|
||||||
a->data.sendtodir.wrap = TRUE;
|
(*a)->data.sendtodir.wrap = TRUE;
|
||||||
a->data.sendtodir.follow = 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.inter.any.interactive = TRUE;
|
||||||
a->data.sendtodir.dir = OB_DIRECTION_EAST;
|
(*a)->data.sendtodir.dir = OB_DIRECTION_EAST;
|
||||||
a->data.sendtodir.linear = FALSE;
|
(*a)->data.sendtodir.linear = FALSE;
|
||||||
a->data.sendtodir.wrap = TRUE;
|
(*a)->data.sendtodir.wrap = TRUE;
|
||||||
a->data.sendtodir.follow = 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.inter.any.interactive = TRUE;
|
||||||
a->data.sendtodir.dir = OB_DIRECTION_NORTH;
|
(*a)->data.sendtodir.dir = OB_DIRECTION_NORTH;
|
||||||
a->data.sendtodir.linear = FALSE;
|
(*a)->data.sendtodir.linear = FALSE;
|
||||||
a->data.sendtodir.wrap = TRUE;
|
(*a)->data.sendtodir.wrap = TRUE;
|
||||||
a->data.sendtodir.follow = 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.inter.any.interactive = TRUE;
|
||||||
a->data.sendtodir.dir = OB_DIRECTION_SOUTH;
|
(*a)->data.sendtodir.dir = OB_DIRECTION_SOUTH;
|
||||||
a->data.sendtodir.linear = FALSE;
|
(*a)->data.sendtodir.linear = FALSE;
|
||||||
a->data.sendtodir.wrap = TRUE;
|
(*a)->data.sendtodir.wrap = TRUE;
|
||||||
a->data.sendtodir.follow = 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.inter.any.interactive = TRUE;
|
||||||
a->data.desktopdir.dir = OB_DIRECTION_WEST;
|
(*a)->data.desktopdir.dir = OB_DIRECTION_WEST;
|
||||||
a->data.desktopdir.linear = TRUE;
|
(*a)->data.desktopdir.linear = TRUE;
|
||||||
a->data.desktopdir.wrap = 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.inter.any.interactive = TRUE;
|
||||||
a->data.desktopdir.dir = OB_DIRECTION_EAST;
|
(*a)->data.desktopdir.dir = OB_DIRECTION_EAST;
|
||||||
a->data.desktopdir.linear = TRUE;
|
(*a)->data.desktopdir.linear = TRUE;
|
||||||
a->data.desktopdir.wrap = 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.inter.any.interactive = TRUE;
|
||||||
a->data.desktopdir.dir = OB_DIRECTION_WEST;
|
(*a)->data.desktopdir.dir = OB_DIRECTION_WEST;
|
||||||
a->data.desktopdir.linear = FALSE;
|
(*a)->data.desktopdir.linear = FALSE;
|
||||||
a->data.desktopdir.wrap = TRUE;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.desktopdir.dir = OB_DIRECTION_EAST;
|
(*a)->data.desktopdir.dir = OB_DIRECTION_EAST;
|
||||||
a->data.desktopdir.linear = FALSE;
|
(*a)->data.desktopdir.linear = FALSE;
|
||||||
a->data.desktopdir.wrap = TRUE;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.desktopdir.dir = OB_DIRECTION_NORTH;
|
(*a)->data.desktopdir.dir = OB_DIRECTION_NORTH;
|
||||||
a->data.desktopdir.linear = FALSE;
|
(*a)->data.desktopdir.linear = FALSE;
|
||||||
a->data.desktopdir.wrap = TRUE;
|
(*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.inter.any.interactive = TRUE;
|
||||||
a->data.desktopdir.dir = OB_DIRECTION_SOUTH;
|
(*a)->data.desktopdir.dir = OB_DIRECTION_SOUTH;
|
||||||
a->data.desktopdir.linear = FALSE;
|
(*a)->data.desktopdir.linear = FALSE;
|
||||||
a->data.desktopdir.wrap = TRUE;
|
(*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.diraction.direction = OB_DIRECTION_EAST;
|
||||||
a->data.cycle.linear = TRUE;
|
|
||||||
a->data.cycle.forward = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.diraction.direction = OB_DIRECTION_WEST;
|
||||||
a->data.cycle.linear = TRUE;
|
|
||||||
a->data.cycle.forward = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.diraction.direction = OB_DIRECTION_NORTH;
|
||||||
a->data.cycle.linear = FALSE;
|
|
||||||
a->data.cycle.forward = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.diraction.direction = OB_DIRECTION_SOUTH;
|
||||||
a->data.cycle.linear = FALSE;
|
|
||||||
a->data.cycle.forward = FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
/* 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! */
|
||||||
void setup_action_top_layer(ObAction *a)
|
if (uact == OB_USER_ACTION_MENU_SELECTION) {
|
||||||
{
|
action_free(*a);
|
||||||
a->data.layer.layer = 1;
|
a = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_action_normal_layer(ObAction *a)
|
|
||||||
{
|
|
||||||
a->data.layer.layer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_action_bottom_layer(ObAction *a)
|
|
||||||
{
|
|
||||||
a->data.layer.layer = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionString actionstrings[] =
|
ActionString actionstrings[] =
|
||||||
|
@ -348,12 +342,12 @@ ActionString actionstrings[] =
|
||||||
{
|
{
|
||||||
"activate",
|
"activate",
|
||||||
action_activate,
|
action_activate,
|
||||||
NULL,
|
NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"focus",
|
"focus",
|
||||||
action_focus,
|
action_focus,
|
||||||
NULL,
|
NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"unfocus",
|
"unfocus",
|
||||||
|
@ -560,11 +554,6 @@ ActionString actionstrings[] =
|
||||||
action_toggle_decorations,
|
action_toggle_decorations,
|
||||||
NULL
|
NULL
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"keyboardmove",
|
|
||||||
action_moveresize,
|
|
||||||
setup_action_move_keyboard
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"move",
|
"move",
|
||||||
action_moveresize,
|
action_moveresize,
|
||||||
|
@ -575,11 +564,6 @@ ActionString actionstrings[] =
|
||||||
action_moveresize,
|
action_moveresize,
|
||||||
setup_action_resize
|
setup_action_resize
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"keyboardresize",
|
|
||||||
action_moveresize,
|
|
||||||
setup_action_resize_keyboard
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"toggleshowdesktop",
|
"toggleshowdesktop",
|
||||||
action_toggle_show_desktop,
|
action_toggle_show_desktop,
|
||||||
|
@ -618,7 +602,7 @@ ActionString actionstrings[] =
|
||||||
{
|
{
|
||||||
"showmenu",
|
"showmenu",
|
||||||
action_showmenu,
|
action_showmenu,
|
||||||
NULL
|
setup_action_showmenu
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"sendtotoplayer",
|
"sendtotoplayer",
|
||||||
|
@ -645,16 +629,6 @@ ActionString actionstrings[] =
|
||||||
action_toggle_layer,
|
action_toggle_layer,
|
||||||
setup_action_bottom_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",
|
"nextwindow",
|
||||||
action_cycle_windows,
|
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;
|
ObAction *a = NULL;
|
||||||
|
gboolean exist = FALSE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; actionstrings[i].name; i++)
|
for (i = 0; actionstrings[i].name; i++)
|
||||||
if (!g_ascii_strcasecmp(name, actionstrings[i].name)) {
|
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)
|
if (actionstrings[i].setup)
|
||||||
actionstrings[i].setup(a);
|
actionstrings[i].setup(&a, uact);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!a)
|
if (!exist)
|
||||||
g_warning("Invalid action '%s' requested. No such action exists.",
|
g_warning("Invalid action '%s' requested. No such action exists.",
|
||||||
name);
|
name);
|
||||||
|
if (!a)
|
||||||
|
g_warning("Invalid use of action '%s'. Action will be ignored.", name);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
|
ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
|
ObUserAction uact)
|
||||||
{
|
{
|
||||||
char *actname;
|
char *actname;
|
||||||
ObAction *act = NULL;
|
ObAction *act = NULL;
|
||||||
xmlNodePtr n;
|
xmlNodePtr n;
|
||||||
|
|
||||||
if (parse_attr_string("name", node, &actname)) {
|
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 (act->func == action_execute || act->func == action_restart) {
|
||||||
if ((n = parse_find_node("execute", node->xmlChildrenNode))) {
|
if ((n = parse_find_node("execute", node->xmlChildrenNode))) {
|
||||||
gchar *s = parse_string(doc, n);
|
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) {
|
} else if (act->func == action_showmenu) {
|
||||||
if ((n = parse_find_node("menu", node->xmlChildrenNode)))
|
if ((n = parse_find_node("menu", node->xmlChildrenNode)))
|
||||||
act->data.showmenu.name = parse_string(doc, n);
|
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 ||
|
} else if (act->func == action_move_relative_horz ||
|
||||||
act->func == action_move_relative_vert ||
|
act->func == action_move_relative_vert ||
|
||||||
act->func == action_resize_relative_horz ||
|
act->func == action_resize_relative_horz ||
|
||||||
act->func == action_resize_relative_vert) {
|
act->func == action_resize_relative_vert) {
|
||||||
if ((n = parse_find_node("delta", node->xmlChildrenNode)))
|
if ((n = parse_find_node("delta", node->xmlChildrenNode)))
|
||||||
act->data.relative.delta = parse_int(doc, n);
|
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) {
|
||||||
|
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) {
|
} else if (act->func == action_desktop_dir) {
|
||||||
if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
|
if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
|
||||||
act->data.desktopdir.wrap = parse_bool(doc, n);
|
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_send_to_desktop_dir) {
|
} else if (act->func == action_send_to_desktop_dir) {
|
||||||
if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
|
if ((n = parse_find_node("wrap", node->xmlChildrenNode)))
|
||||||
act->data.sendtodir.wrap = parse_bool(doc, n);
|
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) {
|
} else if (act->func == action_activate) {
|
||||||
if ((n = parse_find_node("here", node->xmlChildrenNode)))
|
if ((n = parse_find_node("here", node->xmlChildrenNode)))
|
||||||
act->data.activate.here = parse_bool(doc, n);
|
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);
|
g_free(actname);
|
||||||
|
@ -782,6 +763,30 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
|
||||||
return act;
|
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)
|
void action_execute(union ActionData *data)
|
||||||
{
|
{
|
||||||
GError *e = NULL;
|
GError *e = NULL;
|
||||||
|
@ -1089,14 +1094,48 @@ void action_toggle_decorations(union ActionData *data)
|
||||||
client_setup_decor_and_functions(c);
|
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)
|
void action_moveresize(union ActionData *data)
|
||||||
{
|
{
|
||||||
ObClient *c = data->moveresize.any.c;
|
ObClient *c = data->moveresize.any.c;
|
||||||
|
guint32 corner;
|
||||||
|
|
||||||
if (!c || !client_normal(c)) return;
|
if (!c || !client_normal(c)) return;
|
||||||
|
|
||||||
moveresize_start(c, data->moveresize.x, data->moveresize.y,
|
if (data->moveresize.keyboard) {
|
||||||
data->moveresize.button, data->moveresize.corner);
|
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)
|
void action_reconfigure(union ActionData *data)
|
||||||
|
@ -1117,7 +1156,7 @@ void action_exit(union ActionData *data)
|
||||||
void action_showmenu(union ActionData *data)
|
void action_showmenu(union ActionData *data)
|
||||||
{
|
{
|
||||||
if (data->showmenu.name) {
|
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);
|
data->showmenu.any.c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
#define __action_h
|
#define __action_h
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "frame.h"
|
||||||
#include "parser/parse.h"
|
#include "parser/parse.h"
|
||||||
|
|
||||||
|
struct _ObClient;
|
||||||
|
|
||||||
typedef struct _ObAction ObAction;
|
typedef struct _ObAction ObAction;
|
||||||
|
|
||||||
/* These have to all have a Client* at the top even if they don't use it, so
|
/* 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 AnyAction {
|
||||||
struct _ObClient *c;
|
struct _ObClient *c;
|
||||||
gboolean interactive;
|
gboolean interactive;
|
||||||
|
gint x;
|
||||||
|
gint y;
|
||||||
|
gint button;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InteractiveAction {
|
struct InteractiveAction {
|
||||||
|
@ -84,17 +90,13 @@ struct DesktopDirection {
|
||||||
|
|
||||||
struct MoveResize {
|
struct MoveResize {
|
||||||
struct AnyAction any;
|
struct AnyAction any;
|
||||||
int x;
|
gboolean move;
|
||||||
int y;
|
gboolean keyboard;
|
||||||
guint32 corner; /* prop_atoms.net_wm_moveresize_* */
|
|
||||||
guint button;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ShowMenu {
|
struct ShowMenu {
|
||||||
struct AnyAction any;
|
struct AnyAction any;
|
||||||
char *name;
|
char *name;
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CycleWindows {
|
struct CycleWindows {
|
||||||
|
@ -123,6 +125,7 @@ union ActionData {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _ObAction {
|
struct _ObAction {
|
||||||
|
ObUserAction act;
|
||||||
/* The func member acts like an enum to tell which one of the structs in
|
/* The func member acts like an enum to tell which one of the structs in
|
||||||
the data union are valid.
|
the data union are valid.
|
||||||
*/
|
*/
|
||||||
|
@ -130,24 +133,53 @@ struct _ObAction {
|
||||||
union ActionData data;
|
union ActionData data;
|
||||||
};
|
};
|
||||||
|
|
||||||
ObAction *action_new(void (*func)(union ActionData *data));
|
|
||||||
|
|
||||||
/* Creates a new Action from the name of the action
|
/* Creates a new Action from the name of the action
|
||||||
A few action types need data set after making this call still. Check if
|
A few action types need data set after making this call still. Check if
|
||||||
the returned action's "func" is one of these.
|
the returned action's "func" is one of these.
|
||||||
action_execute - the path needs to be set
|
action_execute - the path needs to be set
|
||||||
action_restart - the path can optionally be set
|
action_restart - the path can optionally be set
|
||||||
action_desktop - the destination desktop needs to 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_horz - the delta
|
||||||
action_move_relative_vert - the delta
|
action_move_relative_vert - the delta
|
||||||
action_resize_relative_horz - the delta
|
action_resize_relative_horz - the delta
|
||||||
action_resize_relative_vert - the delta
|
action_resize_relative_vert - the delta
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ObAction *action_from_string(char *name);
|
ObAction *action_from_string(char *name, ObUserAction uact);
|
||||||
ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
|
ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
|
ObUserAction uact);
|
||||||
void action_free(ObAction *a);
|
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 */
|
/* Execute */
|
||||||
void action_execute(union ActionData *data);
|
void action_execute(union ActionData *data);
|
||||||
/* ActivateAction */
|
/* ActivateAction */
|
||||||
|
|
|
@ -40,7 +40,8 @@ static void desk_menu_update(ObMenuFrame *frame, gpointer data)
|
||||||
menu_add_separator(menu, -1);
|
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;
|
act->data.activate.any.c = c;
|
||||||
acts = g_slist_prepend(NULL, act);
|
acts = g_slist_prepend(NULL, act);
|
||||||
e = menu_add_normal(menu, i,
|
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! */
|
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;
|
GSList *it;
|
||||||
|
|
||||||
for (it = self->data.normal.actions; it; it = g_slist_next(it))
|
for (it = self->data.normal.actions; it; it = g_slist_next(it))
|
||||||
{
|
{
|
||||||
ObAction *act = it->data;
|
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];
|
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.desk = desk;
|
||||||
act->data.sendto.follow = FALSE;
|
act->data.sendto.follow = FALSE;
|
||||||
acts = g_slist_prepend(NULL, act);
|
acts = g_slist_prepend(NULL, act);
|
||||||
|
@ -143,13 +144,18 @@ void client_menu_startup()
|
||||||
menu = menu_new(LAYER_MENU_NAME, _("Layer"), NULL);
|
menu = menu_new(LAYER_MENU_NAME, _("Layer"), NULL);
|
||||||
menu_set_update_func(menu, layer_update);
|
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);
|
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);
|
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);
|
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);
|
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 = menu_add_normal(menu, CLIENT_ICONIFY, _("Iconify"), acts);
|
||||||
e->data.normal.mask = ob_rr_theme->iconify_mask;
|
e->data.normal.mask = ob_rr_theme->iconify_mask;
|
||||||
e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
|
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_disabled_color = ob_rr_theme->menu_disabled_color;
|
||||||
e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_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 = menu_add_normal(menu, CLIENT_MAXIMIZE, _("Maximize"), acts);
|
||||||
e->data.normal.mask = ob_rr_theme->max_mask;
|
e->data.normal.mask = ob_rr_theme->max_mask;
|
||||||
e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
|
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_disabled_color = ob_rr_theme->menu_disabled_color;
|
||||||
e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_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);
|
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);
|
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 = menu_add_normal(menu, CLIENT_SHADE, _("Roll up/down"), acts);
|
||||||
e->data.normal.mask = ob_rr_theme->shade_mask;
|
e->data.normal.mask = ob_rr_theme->shade_mask;
|
||||||
e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
|
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_disabled_color = ob_rr_theme->menu_disabled_color;
|
||||||
e->data.normal.mask_selected_color = ob_rr_theme->menu_selected_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_normal(menu, CLIENT_DECORATE, _("Decorate"), acts);
|
||||||
|
|
||||||
menu_add_separator(menu, -1);
|
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);
|
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_normal(menu, CLIENT_RESIZE, _("Resize"), acts);
|
||||||
|
|
||||||
menu_add_separator(menu, -1);
|
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 = menu_add_normal(menu, CLIENT_CLOSE, _("Close"), acts);
|
||||||
e->data.normal.mask = ob_rr_theme->close_mask;
|
e->data.normal.mask = ob_rr_theme->close_mask;
|
||||||
e->data.normal.mask_normal_color = ob_rr_theme->menu_color;
|
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) {
|
if (keylist) {
|
||||||
nact = parse_find_node("action", node);
|
nact = parse_find_node("action", node);
|
||||||
while (nact) {
|
while (nact) {
|
||||||
if ((action = action_parse(i, doc, nact))) {
|
if ((action = action_parse(i, doc, nact,
|
||||||
/* validate that its okay for a key binding */
|
OB_USER_ACTION_KEYBOARD_KEY)))
|
||||||
if (action->func == action_moveresize &&
|
keyboard_bind(keylist, action);
|
||||||
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);
|
|
||||||
}
|
|
||||||
nact = parse_find_node("action", nact->next);
|
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;
|
xmlNodePtr n, nbut, nact;
|
||||||
char *buttonstr;
|
char *buttonstr;
|
||||||
char *contextstr;
|
char *contextstr;
|
||||||
|
ObUserAction uact;
|
||||||
ObMouseAction mact;
|
ObMouseAction mact;
|
||||||
ObAction *action;
|
ObAction *action;
|
||||||
|
|
||||||
|
@ -141,44 +131,27 @@ static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
|
||||||
while (nbut) {
|
while (nbut) {
|
||||||
if (!parse_attr_string("button", nbut, &buttonstr))
|
if (!parse_attr_string("button", nbut, &buttonstr))
|
||||||
goto next_nbut;
|
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;
|
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;
|
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;
|
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;
|
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;
|
mact = OB_MOUSE_ACTION_MOTION;
|
||||||
else
|
} else
|
||||||
goto next_nbut;
|
goto next_nbut;
|
||||||
nact = parse_find_node("action", nbut->xmlChildrenNode);
|
nact = parse_find_node("action", nbut->xmlChildrenNode);
|
||||||
while (nact) {
|
while (nact) {
|
||||||
if ((action = action_parse(i, doc, nact))) {
|
if ((action = action_parse(i, doc, nact, uact)))
|
||||||
/* validate that its okay for a mouse binding*/
|
mouse_bind(buttonstr, contextstr, mact, action);
|
||||||
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);
|
|
||||||
}
|
|
||||||
nact = parse_find_node("action", nact->next);
|
nact = parse_find_node("action", nact->next);
|
||||||
}
|
}
|
||||||
g_free(buttonstr);
|
g_free(buttonstr);
|
||||||
|
|
|
@ -1126,8 +1126,7 @@ static void event_handle_menu(XEvent *ev)
|
||||||
else {
|
else {
|
||||||
if ((e = menu_entry_frame_under(ev->xbutton.x_root,
|
if ((e = menu_entry_frame_under(ev->xbutton.x_root,
|
||||||
ev->xbutton.y_root)))
|
ev->xbutton.y_root)))
|
||||||
menu_entry_frame_execute(e,
|
menu_entry_frame_execute(e, ev->xbutton.state);
|
||||||
!(ev->xbutton.state & ControlMask));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
|
@ -1145,8 +1144,7 @@ static void event_handle_menu(XEvent *ev)
|
||||||
else if (ev->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
|
else if (ev->xkey.keycode == ob_keycode(OB_KEY_RETURN)) {
|
||||||
ObMenuFrame *f;
|
ObMenuFrame *f;
|
||||||
if ((f = find_active_menu()))
|
if ((f = find_active_menu()))
|
||||||
menu_entry_frame_execute(f->selected,
|
menu_entry_frame_execute(f->selected, ev->xkey.state);
|
||||||
!(ev->xkey.state & ControlMask));
|
|
||||||
} else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) {
|
} else if (ev->xkey.keycode == ob_keycode(OB_KEY_LEFT)) {
|
||||||
ObMenuFrame *f;
|
ObMenuFrame *f;
|
||||||
if ((f = find_active_menu()) && f->parent)
|
if ((f = find_active_menu()) && f->parent)
|
||||||
|
|
|
@ -133,6 +133,8 @@ void keyboard_interactive_grab(guint state, ObClient *client,
|
||||||
{
|
{
|
||||||
ObInteractiveState *s;
|
ObInteractiveState *s;
|
||||||
|
|
||||||
|
g_assert(action->data.any.interactive);
|
||||||
|
|
||||||
if (!interactive_states) {
|
if (!interactive_states) {
|
||||||
if (!grab_keyboard(TRUE))
|
if (!grab_keyboard(TRUE))
|
||||||
return;
|
return;
|
||||||
|
@ -179,12 +181,8 @@ gboolean keyboard_process_interactive_grab(const XEvent *e,
|
||||||
cancel = done = TRUE;
|
cancel = done = TRUE;
|
||||||
}
|
}
|
||||||
if (done) {
|
if (done) {
|
||||||
g_assert(s->action->data.any.interactive);
|
action_run_interactive(s->action, s->client,
|
||||||
|
e->xkey.state, cancel, TRUE);
|
||||||
s->action->data.inter.cancel = cancel;
|
|
||||||
s->action->data.inter.final = TRUE;
|
|
||||||
|
|
||||||
s->action->func(&s->action->data);
|
|
||||||
|
|
||||||
g_free(s);
|
g_free(s);
|
||||||
|
|
||||||
|
@ -221,7 +219,8 @@ void keyboard_event(ObClient *client, const XEvent *e)
|
||||||
p = curpos->first_child;
|
p = curpos->first_child;
|
||||||
while (p) {
|
while (p) {
|
||||||
if (p->key == e->xkey.keycode &&
|
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 */
|
if (p->first_child != NULL) { /* part of a chain */
|
||||||
ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
|
ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
|
||||||
/* 5 second timeout for chains */
|
/* 5 second timeout for chains */
|
||||||
|
@ -232,32 +231,10 @@ void keyboard_event(ObClient *client, const XEvent *e)
|
||||||
grab_keys(TRUE);
|
grab_keys(TRUE);
|
||||||
} else {
|
} else {
|
||||||
GSList *it;
|
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) {
|
for (it = p->actions; it; it = it->next)
|
||||||
screen_pointer_pos(&act->data.moveresize.x,
|
action_run_key(it->data, client, e->xkey.state,
|
||||||
&act->data.moveresize.y);
|
e->xkey.x_root, e->xkey.y_root);
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
keyboard_reset_chains();
|
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)
|
for (node = node->xmlChildrenNode; node; node = node->next)
|
||||||
if (!xmlStrcasecmp(node->name, (const xmlChar*) "action"))
|
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);
|
menu_add_normal(state->parent, -1, label, acts);
|
||||||
g_free(label);
|
g_free(label);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,8 @@ typedef struct _ObSubmenuMenuEntry ObSubmenuMenuEntry;
|
||||||
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
|
typedef struct _ObSeparatorMenuEntry ObSeparatorMenuEntry;
|
||||||
|
|
||||||
typedef void (*ObMenuUpdateFunc)(struct _ObMenuFrame *frame, gpointer data);
|
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);
|
typedef void (*ObMenuDestroyFunc)(struct _ObMenu *menu, gpointer data);
|
||||||
|
|
||||||
struct _ObMenu
|
struct _ObMenu
|
||||||
|
|
|
@ -711,7 +711,7 @@ void menu_entry_frame_show_submenu(ObMenuEntryFrame *self)
|
||||||
menu_frame_show(f, self->frame);
|
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 &&
|
if (self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
|
||||||
self->entry->data.normal.enabled)
|
self->entry->data.normal.enabled)
|
||||||
|
@ -725,31 +725,16 @@ void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide)
|
||||||
ObClient *client = self->frame->client;
|
ObClient *client = self->frame->client;
|
||||||
|
|
||||||
/* release grabs before executing the shit */
|
/* release grabs before executing the shit */
|
||||||
if (hide)
|
if (!(state & ControlMask))
|
||||||
menu_frame_hide_all();
|
menu_frame_hide_all();
|
||||||
|
|
||||||
if (func)
|
if (func)
|
||||||
func(entry, data);
|
func(entry, state, data);
|
||||||
else {
|
else {
|
||||||
GSList *it;
|
GSList *it;
|
||||||
|
|
||||||
for (it = acts; it; it = g_slist_next(it))
|
for (it = acts; it; it = g_slist_next(it))
|
||||||
{
|
action_run(it->data, client, state);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_show_submenu(ObMenuEntryFrame *self);
|
||||||
|
|
||||||
void menu_entry_frame_execute(ObMenuEntryFrame *self, gboolean hide);
|
void menu_entry_frame_execute(ObMenuEntryFrame *self, guint state);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -62,4 +62,24 @@ typedef enum
|
||||||
OB_CORNER_BOTTOMRIGHT
|
OB_CORNER_BOTTOMRIGHT
|
||||||
} ObCorner;
|
} 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
|
#endif
|
||||||
|
|
156
openbox/mouse.c
156
openbox/mouse.c
|
@ -9,13 +9,12 @@
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
#include "translate.h"
|
#include "translate.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "keyboard.h"
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
guint state;
|
guint state;
|
||||||
guint button;
|
guint button;
|
||||||
GSList *actions[OB_MOUSE_NUM_ACTIONS]; /* lists of Action pointers */
|
GSList *actions[OB_NUM_MOUSE_ACTIONS]; /* lists of Action pointers */
|
||||||
} ObMouseBinding;
|
} ObMouseBinding;
|
||||||
|
|
||||||
#define FRAME_CONTEXT(co, cl) ((cl && cl->type != OB_CLIENT_TYPE_DESKTOP) ? \
|
#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;
|
GSList *it;
|
||||||
|
|
||||||
for (i = 0; i < OB_FRAME_NUM_CONTEXTS; ++i)
|
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 */
|
/* grab/ungrab the button */
|
||||||
ObMouseBinding *b = it->data;
|
ObMouseBinding *b = it->data;
|
||||||
Window win;
|
Window win;
|
||||||
|
@ -75,14 +74,14 @@ static void clearall()
|
||||||
|
|
||||||
for(i = 0; i < OB_FRAME_NUM_CONTEXTS; ++i) {
|
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 = it->next) {
|
||||||
|
ObMouseBinding *b = it->data;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
ObMouseBinding *b = it->data;
|
for (j = 0; j < OB_NUM_MOUSE_ACTIONS; ++j) {
|
||||||
for (j = 0; j < OB_MOUSE_NUM_ACTIONS; ++j) {
|
|
||||||
GSList *it;
|
GSList *it;
|
||||||
for (it = b->actions[j]; it; it = it->next) {
|
|
||||||
|
for (it = b->actions[j]; it; it = it->next)
|
||||||
action_free(it->data);
|
action_free(it->data);
|
||||||
}
|
|
||||||
g_slist_free(b->actions[j]);
|
g_slist_free(b->actions[j]);
|
||||||
}
|
}
|
||||||
g_free(b);
|
g_free(b);
|
||||||
|
@ -92,9 +91,9 @@ static void clearall()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean fire_button(ObMouseAction a, ObFrameContext context,
|
static gboolean fire_binding(ObMouseAction a, ObFrameContext context,
|
||||||
ObClient *c, guint state,
|
ObClient *c, guint state,
|
||||||
guint button, int x, int y)
|
guint button, int x, int y)
|
||||||
{
|
{
|
||||||
GSList *it;
|
GSList *it;
|
||||||
ObMouseBinding *b;
|
ObMouseBinding *b;
|
||||||
|
@ -107,85 +106,11 @@ static gboolean fire_button(ObMouseAction a, ObFrameContext context,
|
||||||
/* if not bound, then nothing to do! */
|
/* if not bound, then nothing to do! */
|
||||||
if (it == NULL) return FALSE;
|
if (it == NULL) return FALSE;
|
||||||
|
|
||||||
for (it = b->actions[a]; it; it = it->next) {
|
for (it = b->actions[a]; it; it = it->next)
|
||||||
ObAction *act = it->data;
|
action_run_mouse(it->data, c, context, state, button, x, y);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
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)
|
void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
|
||||||
{
|
{
|
||||||
static Time ltime;
|
static Time ltime;
|
||||||
|
@ -203,10 +128,10 @@ void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
|
||||||
button = e->xbutton.button;
|
button = e->xbutton.button;
|
||||||
state = e->xbutton.state;
|
state = e->xbutton.state;
|
||||||
|
|
||||||
fire_button(OB_MOUSE_ACTION_PRESS, context,
|
fire_binding(OB_MOUSE_ACTION_PRESS, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root, e->xbutton.y_root);
|
e->xbutton.x_root, e->xbutton.y_root);
|
||||||
|
|
||||||
if (CLIENT_CONTEXT(context, client)) {
|
if (CLIENT_CONTEXT(context, client)) {
|
||||||
/* Replay the event, so it goes to the 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;
|
state = 0;
|
||||||
ltime = e->xbutton.time;
|
ltime = e->xbutton.time;
|
||||||
}
|
}
|
||||||
fire_button(OB_MOUSE_ACTION_RELEASE, context,
|
fire_binding(OB_MOUSE_ACTION_RELEASE, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root, e->xbutton.y_root);
|
e->xbutton.x_root, e->xbutton.y_root);
|
||||||
if (click)
|
if (click)
|
||||||
fire_button(OB_MOUSE_ACTION_CLICK, context,
|
fire_binding(OB_MOUSE_ACTION_CLICK, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root,
|
e->xbutton.x_root,
|
||||||
e->xbutton.y_root);
|
e->xbutton.y_root);
|
||||||
if (dclick)
|
if (dclick)
|
||||||
fire_button(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
|
fire_binding(OB_MOUSE_ACTION_DOUBLE_CLICK, context,
|
||||||
client, e->xbutton.state,
|
client, e->xbutton.state,
|
||||||
e->xbutton.button,
|
e->xbutton.button,
|
||||||
e->xbutton.x_root,
|
e->xbutton.x_root,
|
||||||
e->xbutton.y_root);
|
e->xbutton.y_root);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
|
@ -276,7 +201,6 @@ void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
|
||||||
config_mouse_threshold ||
|
config_mouse_threshold ||
|
||||||
ABS(e->xmotion.y_root - py) >=
|
ABS(e->xmotion.y_root - py) >=
|
||||||
config_mouse_threshold) {
|
config_mouse_threshold) {
|
||||||
guint32 corner;
|
|
||||||
|
|
||||||
/* You can't drag on buttons */
|
/* You can't drag on buttons */
|
||||||
if (context == OB_FRAME_CONTEXT_MAXIMIZE ||
|
if (context == OB_FRAME_CONTEXT_MAXIMIZE ||
|
||||||
|
@ -287,26 +211,8 @@ void mouse_event(ObClient *client, ObFrameContext context, XEvent *e)
|
||||||
context == OB_FRAME_CONTEXT_CLOSE)
|
context == OB_FRAME_CONTEXT_CLOSE)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!client)
|
fire_binding(OB_MOUSE_ACTION_MOTION, context,
|
||||||
corner = prop_atoms.net_wm_moveresize_size_bottomright;
|
client, state, button, px, py);
|
||||||
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);
|
|
||||||
button = 0;
|
button = 0;
|
||||||
state = 0;
|
state = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,10 @@
|
||||||
|
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
#include "frame.h"
|
#include "frame.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
#include <X11/Xlib.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_startup(gboolean reconfig);
|
||||||
void mouse_shutdown(gboolean reconfig);
|
void mouse_shutdown(gboolean reconfig);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue