inline void client_action_end(union ActionData *data)
{
if (config_focus_follow)
- if (data->any.context != OB_FRAME_CONTEXT_CLIENT) {
- if (!data->any.button) {
- grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
- } else {
- ObClient *c;
-
- /* usually this is sorta redundant, but with a press action
- the enter event will come as a GrabNotify which is
- ignored, so this will handle that case */
- if ((c = client_under_pointer()))
- event_enter_client(c);
- }
- }
+ if (data->any.context != OB_FRAME_CONTEXT_CLIENT && !data->any.button)
+ grab_pointer(FALSE, FALSE, OB_CURSOR_NONE);
}
typedef struct
(*a)->data.cycle.forward = TRUE;
(*a)->data.cycle.dialog = TRUE;
(*a)->data.cycle.dock_windows = FALSE;
+ (*a)->data.cycle.all_desktops = FALSE;
}
void setup_action_cycle_windows_previous(ObAction **a, ObUserAction uact)
(*a)->data.cycle.forward = FALSE;
(*a)->data.cycle.dialog = TRUE;
(*a)->data.cycle.dock_windows = FALSE;
+ (*a)->data.cycle.all_desktops = FALSE;
}
void setup_action_movefromedge_north(ObAction **a, ObUserAction uact)
{
"activate",
action_activate,
- setup_client_action
+ setup_action_focus
},
{
"focus",
action_growtoedge,
setup_action_growtoedge_east
},
+ {
+ "breakchroot",
+ action_break_chroot,
+ NULL
+ },
{
NULL,
NULL,
act->data.cycle.dialog = parse_bool(doc, n);
if ((n = parse_find_node("panels", node->xmlChildrenNode)))
act->data.cycle.dock_windows = parse_bool(doc, n);
+ if ((n = parse_find_node("allDesktops",
+ node->xmlChildrenNode)))
+ act->data.cycle.all_desktops = parse_bool(doc, n);
} else if (act->func == action_directional_focus) {
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.interdiraction.dialog = parse_bool(doc, n);
if (a->data.any.interactive || a->func == action_moveresize) {
/* interactive actions are not queued */
a->func(&a->data);
+ } else if ((context == OB_FRAME_CONTEXT_CLIENT ||
+ (c && c->type == OB_CLIENT_TYPE_DESKTOP &&
+ context == OB_FRAME_CONTEXT_DESKTOP)) &&
+ (a->func == action_focus ||
+ a->func == action_activate ||
+ a->func == action_showmenu))
+ {
+ /* XXX MORE UGLY HACK
+ actions from clicks on client windows are NOT queued.
+ this solves the mysterious click-and-drag-doesnt-work
+ problem. it was because the window gets focused and stuff
+ after the button event has already been passed through. i
+ dont really know why it should care but it does and it makes
+ a difference.
+
+ however this very bogus ! !
+ we want to send the button press to the window BEFORE
+ we do the action because the action might move the windows
+ (eg change desktops) and then the button press ends up on
+ the completely wrong window !
+ so, this is just for that bug, and it will only NOT queue it
+ if it is a focusing action that can be used with the mouse
+ pointer. ugh.
+
+ also with the menus, there is a race going on. if the
+ desktop wants to pop up a menu, and we do to, we send them
+ the button before we pop up the menu, so they pop up their
+ menu first. but not always. if we pop up our menu before
+ sending them the button press, then the result is
+ deterministic. yay.
+ */
+ a->func(&a->data);
} else
ob_main_loop_queue_action(ob_main_loop, a);
}
void action_activate(union ActionData *data)
{
- /* similar to the openbox dock for dockapps, don't let user actions give
- focus to 3rd-party docks (panels) either (unless they ask for it
- themselves). */
- if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
- /* if using focus_delay, stop the timer now so that focus doesn't go
- moving on us */
- event_halt_focus_delay();
+ if (data->client.any.c) {
+ /* similar to the openbox dock for dockapps, don't let user actions
+ give focus to 3rd-party docks (panels) either (unless they ask for
+ it themselves). */
+ if (data->client.any.c->type != OB_CLIENT_TYPE_DOCK) {
+ /* if using focus_delay, stop the timer now so that focus doesn't
+ go moving on us */
+ event_halt_focus_delay();
- client_activate(data->activate.any.c, data->activate.here, TRUE);
+ client_activate(data->activate.any.c, data->activate.here, TRUE);
+ }
+ } else {
+ /* focus action on something other than a client, make keybindings
+ work for this openbox instance, but don't focus any specific client
+ */
+ focus_nothing();
}
}
if (cit == c) break;
if (client_normal(cit) == client_normal(c) &&
- cit->layer == c->layer &&
- cit->frame->visible &&
- !client_search_transient(c, cit))
+ cit->layer == c->layer &&
+ cit->frame->visible &&
+ !client_search_transient(c, cit))
{
if (RECT_INTERSECTS_RECT(cit->frame->area, c->frame->area)) {
raise = TRUE;
h = oh + data->relative.deltay * c->size_inc.height
+ data->relative.deltayu * c->size_inc.height;
- client_try_configure(c, OB_CORNER_TOPLEFT, &x, &y, &w, &h, &lw, &lh, TRUE);
+ client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE);
client_move_resize(c, x + (ow - w), y + (oh - h), w, h);
client_action_end(data);
}
data->sendto.desk == DESKTOP_ALL) {
client_set_desktop(c, data->sendto.desk, data->sendto.follow);
if (data->sendto.follow)
- screen_set_desktop(data->sendto.desk);
+ screen_set_desktop(data->sendto.desk, TRUE);
}
}
if (data->desktop.desk < screen_num_desktops ||
data->desktop.desk == DESKTOP_ALL)
{
- screen_set_desktop(data->desktop.desk);
+ screen_set_desktop(data->desktop.desk, TRUE);
if (data->inter.any.interactive)
screen_desktop_popup(data->desktop.desk, TRUE);
}
} else if (data->inter.cancel) {
- screen_set_desktop(first);
+ screen_set_desktop(first, TRUE);
}
if (!data->inter.any.interactive || data->inter.final) {
!data->sendtodir.inter.final ||
data->sendtodir.inter.cancel)
{
- screen_set_desktop(d);
+ screen_set_desktop(d, TRUE);
}
}
{
client_set_desktop(c, d, data->sendtodir.follow);
if (data->sendtodir.follow)
- screen_set_desktop(d);
+ screen_set_desktop(d, TRUE);
}
}
void action_desktop_last(union ActionData *data)
{
- screen_set_desktop(screen_last_desktop);
+ screen_set_desktop(screen_last_desktop, TRUE);
}
void action_toggle_decorations(union ActionData *data)
c->frame->size.right,
c->area.height + c->frame->size.top +
c->frame->size.bottom));
- const gchar *c;
- if (corner == prop_atoms.net_wm_moveresize_size_topright)
- c = "topright";
- else if (corner == prop_atoms.net_wm_moveresize_size_top)
- c = "top";
- else if (corner == prop_atoms.net_wm_moveresize_size_topleft)
- c = "topleft";
- else if (corner == prop_atoms.net_wm_moveresize_size_right)
- c = "right";
- else if (corner == prop_atoms.net_wm_moveresize_move)
- c = "middle";
- else if (corner == prop_atoms.net_wm_moveresize_size_left)
- c = "left";
- else if (corner == prop_atoms.net_wm_moveresize_size_bottomright)
- c = "bottomright";
- else if (corner == prop_atoms.net_wm_moveresize_size_bottom)
- c = "bottom";
- else if (corner == prop_atoms.net_wm_moveresize_size_bottomleft)
- c = "bottomleft";
- ob_debug("corner: %s\n", c);
}
moveresize_start(c, data->any.x, data->any.y, data->any.button, corner);
{
if (data->showmenu.name) {
menu_show(data->showmenu.name, data->any.x, data->any.y,
- data->showmenu.any.c);
+ data->any.button, data->showmenu.any.c);
}
}
event_halt_focus_delay();
focus_cycle(data->cycle.forward,
+ data->cycle.all_desktops,
data->cycle.dock_windows,
data->cycle.linear, data->any.interactive,
data->cycle.dialog,
default:
g_assert_not_reached();
}
- frame_frame_gravity(c->frame, &x, &y);
+ frame_frame_gravity(c->frame, &x, &y, c->area.width, c->area.height);
client_action_start(data);
client_move(c, x, y);
client_action_end(data);
ObClient *c = data->diraction.any.c;
Rect *a;
- //FIXME growtoedge resizes shaded windows to 0 height
- if (c->shaded)
- return;
-
a = screen_area(c->desktop);
x = c->frame->area.x;
y = c->frame->area.y;
- width = c->frame->area.width;
- height = c->frame->area.height;
+ /* get the unshaded frame's dimensions..if it is shaded */
+ width = c->area.width + c->frame->size.left + c->frame->size.right;
+ height = c->area.height + c->frame->size.top + c->frame->size.bottom;
switch(data->diraction.direction) {
case OB_DIRECTION_NORTH:
+ if (c->shaded) break; /* don't allow vertical resize if shaded */
+
dest = client_directional_edge_search(c, OB_DIRECTION_NORTH, FALSE);
if (a->y == y)
- height = c->frame->area.height / 2;
+ height = height / 2;
else {
- height = c->frame->area.y + c->frame->area.height - dest;
+ height = c->frame->area.y + height - dest;
y = dest;
}
break;
case OB_DIRECTION_WEST:
dest = client_directional_edge_search(c, OB_DIRECTION_WEST, FALSE);
if (a->x == x)
- width = c->frame->area.width / 2;
+ width = width / 2;
else {
- width = c->frame->area.x + c->frame->area.width - dest;
+ width = c->frame->area.x + width - dest;
x = dest;
}
break;
case OB_DIRECTION_SOUTH:
+ if (c->shaded) break; /* don't allow vertical resize if shaded */
+
dest = client_directional_edge_search(c, OB_DIRECTION_SOUTH, FALSE);
if (a->y + a->height == y + c->frame->area.height) {
height = c->frame->area.height / 2;
default:
g_assert_not_reached();
}
- frame_frame_gravity(c->frame, &x, &y);
width -= c->frame->size.left + c->frame->size.right;
height -= c->frame->size.top + c->frame->size.bottom;
+ frame_frame_gravity(c->frame, &x, &y, width, height);
client_action_start(data);
client_move_resize(c, x, y, width, height);
client_action_end(data);
void action_toggle_show_desktop(union ActionData *data)
{
- screen_show_desktop(!screen_showing_desktop);
+ screen_show_desktop(!screen_showing_desktop, TRUE);
}
void action_show_desktop(union ActionData *data)
{
- screen_show_desktop(TRUE);
+ screen_show_desktop(TRUE, TRUE);
}
void action_unshow_desktop(union ActionData *data)
{
- screen_show_desktop(FALSE);
+ screen_show_desktop(FALSE, TRUE);
+}
+
+void action_break_chroot(union ActionData *data)
+{
+ /* break out of one chroot */
+ keyboard_reset_chains(1);
}