X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Faction.c;h=797552f69abd2c649704f496fcf29c5798ef2795;hb=affc84cc96e9e3eebfea66fd6a987e6ef4217dc1;hp=b74dfa95e3f632005db287aecc487777c2572583;hpb=f20182804656b9f1a705c93bc1f42f92ab3590ef;p=chaz%2Fopenbox diff --git a/openbox/action.c b/openbox/action.c index b74dfa95..797552f6 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -48,19 +48,8 @@ inline void client_action_start(union ActionData *data) 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 @@ -505,7 +494,7 @@ ActionString actionstrings[] = { "activate", action_activate, - setup_client_action + setup_action_focus }, { "focus", @@ -892,6 +881,11 @@ ActionString actionstrings[] = action_growtoedge, setup_action_growtoedge_east }, + { + "breakchroot", + action_break_chroot, + NULL + }, { NULL, NULL, @@ -1093,6 +1087,38 @@ void action_run_list(GSList *acts, ObClient *c, ObFrameContext context, 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); } @@ -1167,15 +1193,22 @@ void action_execute(union ActionData *data) 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(); } } @@ -1230,9 +1263,9 @@ void action_raiselower(union ActionData *data) 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; @@ -1389,7 +1422,7 @@ void action_resize_relative(union ActionData *data) 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); } @@ -1566,41 +1599,97 @@ void action_toggle_decorations(union ActionData *data) static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch) { - if (config_resize_four_corners) { - 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; - } - } else { - /* let's make x and y client relative instead of screen relative */ - x = x - cx; - y = y - cy; - if (y < -4*x*ch/cw+7*ch/3 && y > -ch*x/4/cw+2*ch/3) - return prop_atoms.net_wm_moveresize_size_topleft; - else if (y > 5*ch/9 && y > 4*x*ch/cw-15*ch/9) - return prop_atoms.net_wm_moveresize_size_top; - else if (y > ch*x/4/cw+5*ch/12) - return prop_atoms.net_wm_moveresize_size_topright; - else if (x < 4*cw/9 && y > ch*x/4/cw+ch/3) - return prop_atoms.net_wm_moveresize_size_left; - else if (x > 5*cw/9 && y > -ch*x/4/cw+7*ch/12) - return prop_atoms.net_wm_moveresize_size_right; - else if (y > 4*ch*x/cw-4*ch/3) - return prop_atoms.net_wm_moveresize_size_bottomleft; - else if (y < 4*ch/9 && y < -4*x*ch/cw+8*ch/3) - return prop_atoms.net_wm_moveresize_size_bottom; - else if (y > 5*cw/9) - return prop_atoms.net_wm_moveresize_size_bottomright; - else - return prop_atoms.net_wm_moveresize_move; - } + /* let's make x and y client relative instead of screen relative */ + x = x - cx; + y = ch - (y - cy); /* y is inverted, 0 is at the bottom of the window */ + +#define X x*ch/cw +#define A -4*X + 7*ch/3 +#define B 4*X -15*ch/9 +#define C -X/4 + 2*ch/3 +#define D X/4 + 5*ch/12 +#define E X/4 + ch/3 +#define F -X/4 + 7*ch/12 +#define G 4*X - 4*ch/3 +#define H -4*X + 8*ch/3 +#define a (y > 5*ch/9) +#define b (x < 4*cw/9) +#define c (x > 5*cw/9) +#define d (y < 4*ch/9) + + /* + Each of these defines (except X which is just there for fun), represents + the equation of a line. The lines they represent are shown in the diagram + below. Checking y against these lines, we are able to choose a region + of the window as shown. + + +---------------------A-------|-------|-------B---------------------+ + | |A B| | + | |A | | B| | + | | A B | | + | | A | | B | | + | | A B | | + | | A | | B | | + | northwest | A north B | northeast | + | | A | | B | | + | | A B | | + C---------------------+----A--+-------+--B----+---------------------D + |CCCCCCC | A B | DDDDDDD| + | CCCCCCCC | A | | B | DDDDDDDD | + | CCCCCCC A B DDDDDDD | + - - - - - - - - - - - +CCCCCCC+aaaaaaa+DDDDDDD+ - - - - - - - - - - - + | | b c | | + | west | b move c | east | + | | b c | | + - - - - - - - - - - - +EEEEEEE+ddddddd+FFFFFFF+- - - - - - - - - - - + | EEEEEEE G H FFFFFFF | + | EEEEEEEE | G | | H | FFFFFFFF | + |EEEEEEE | G H | FFFFFFF| + E---------------------+----G--+-------+--H----+---------------------F + | | G H | | + | | G | | H | | + | southwest | G south H | southeast | + | | G | | H | | + | | G H | | + | | G | | H | | + | | G H | | + | |G | | H| | + | |G H| | + +---------------------G-------|-------|-------H---------------------+ + */ + + if (y < A && y >= C) + return prop_atoms.net_wm_moveresize_size_topleft; + else if (y >= A && y >= B && a) + return prop_atoms.net_wm_moveresize_size_top; + else if (y < B && y >= D) + return prop_atoms.net_wm_moveresize_size_topright; + else if (y < C && y >= E && b) + return prop_atoms.net_wm_moveresize_size_left; + else if (y < D && y >= F && c) + return prop_atoms.net_wm_moveresize_size_right; + else if (y < E && y >= G) + return prop_atoms.net_wm_moveresize_size_bottomleft; + else if (y < G && y < H && d) + return prop_atoms.net_wm_moveresize_size_bottom; + else if (y >= H && y < F) + return prop_atoms.net_wm_moveresize_size_bottomright; + else + return prop_atoms.net_wm_moveresize_move; + +#undef X +#undef A +#undef B +#undef C +#undef D +#undef E +#undef F +#undef G +#undef H +#undef a +#undef b +#undef c +#undef d } void action_moveresize(union ActionData *data) @@ -1627,6 +1716,26 @@ void action_moveresize(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); @@ -1651,7 +1760,7 @@ void action_showmenu(union ActionData *data) { 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); } } @@ -1714,7 +1823,7 @@ void action_movetoedge(union ActionData *data) 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); @@ -1726,36 +1835,37 @@ void action_growtoedge(union ActionData *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; @@ -1778,9 +1888,9 @@ void action_growtoedge(union ActionData *data) 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); @@ -1811,15 +1921,21 @@ void action_toggle_dockautohide(union ActionData *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); }