diff options
Diffstat (limited to 'openbox/actions')
| -rw-r--r-- | openbox/actions/desktop.c | 349 | ||||
| -rw-r--r-- | openbox/actions/growtoedge.c | 146 | ||||
| -rw-r--r-- | openbox/actions/if.c | 22 | ||||
| -rw-r--r-- | openbox/actions/resize.c | 7 | ||||
| -rw-r--r-- | openbox/actions/showdesktop.c | 39 | ||||
| -rw-r--r-- | openbox/actions/showmenu.c | 84 |
6 files changed, 328 insertions, 319 deletions
diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c index 8dadf550..c2f73c6b 100644 --- a/openbox/actions/desktop.c +++ b/openbox/actions/desktop.c @@ -26,131 +26,62 @@ typedef struct { } u; gboolean send; gboolean follow; - gboolean interactive; } Options; -static gpointer setup_go_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_send_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); +static gpointer setup_func(xmlNodePtr node); +static gpointer setup_send_func(xmlNodePtr node); static void free_func(gpointer o); static gboolean run_func(ObActionsData *data, gpointer options); -static gboolean i_pre_func(guint state, gpointer options); -static gboolean i_input_func(guint initial_state, - XEvent *e, - ObtIC *ic, - gpointer options, - gboolean *used); -static void i_post_func(gpointer options); - /* 3.4-compatibility */ static gpointer setup_go_last_func(xmlNodePtr node); static gpointer setup_send_last_func(xmlNodePtr node); static gpointer setup_go_abs_func(xmlNodePtr node); -static gpointer setup_go_next_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_send_next_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_go_prev_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_send_prev_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_go_left_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_send_left_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_go_right_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_send_right_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_go_up_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_send_up_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_go_down_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); -static gpointer setup_send_down_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post); +static gpointer setup_go_next_func(xmlNodePtr node); +static gpointer setup_send_next_func(xmlNodePtr node); +static gpointer setup_go_prev_func(xmlNodePtr node); +static gpointer setup_send_prev_func(xmlNodePtr node); +static gpointer setup_go_left_func(xmlNodePtr node); +static gpointer setup_send_left_func(xmlNodePtr node); +static gpointer setup_go_right_func(xmlNodePtr node); +static gpointer setup_send_right_func(xmlNodePtr node); +static gpointer setup_go_up_func(xmlNodePtr node); +static gpointer setup_send_up_func(xmlNodePtr node); +static gpointer setup_go_down_func(xmlNodePtr node); +static gpointer setup_send_down_func(xmlNodePtr node); void action_desktop_startup(void) { - actions_register_i("GoToDesktop", setup_go_func, free_func, run_func); - actions_register_i("SendToDesktop", setup_send_func, free_func, run_func); + actions_register("GoToDesktop", setup_func, free_func, run_func); + actions_register("SendToDesktop", setup_send_func, free_func, run_func); /* 3.4-compatibility */ actions_register("DesktopLast", setup_go_last_func, free_func, run_func); actions_register("SendToDesktopLast", setup_send_last_func, free_func, run_func); actions_register("Desktop", setup_go_abs_func, free_func, run_func); - actions_register_i("DesktopNext", setup_go_next_func, free_func, run_func); - actions_register_i("SendToDesktopNext", setup_send_next_func, - free_func, run_func); - actions_register_i("DesktopPrevious", setup_go_prev_func, - free_func, run_func); - actions_register_i("SendToDesktopPrevious", setup_send_prev_func, - free_func, run_func); - actions_register_i("DesktopLeft", setup_go_left_func, free_func, run_func); - actions_register_i("SendToDesktopLeft", setup_send_left_func, - free_func, run_func); - actions_register_i("DesktopRight", setup_go_right_func, - free_func, run_func); - actions_register_i("SendToDesktopRight", setup_send_right_func, - free_func, run_func); - actions_register_i("DesktopUp", setup_go_up_func, free_func, run_func); - actions_register_i("SendToDesktopUp", setup_send_up_func, - free_func, run_func); - actions_register_i("DesktopDown", setup_go_down_func, free_func, run_func); - actions_register_i("SendToDesktopDown", setup_send_down_func, - free_func, run_func); + actions_register("DesktopNext", setup_go_next_func, free_func, run_func); + actions_register("SendToDesktopNext", setup_send_next_func, + free_func, run_func); + actions_register("DesktopPrevious", setup_go_prev_func, + free_func, run_func); + actions_register("SendToDesktopPrevious", setup_send_prev_func, + free_func, run_func); + actions_register("DesktopLeft", setup_go_left_func, free_func, run_func); + actions_register("SendToDesktopLeft", setup_send_left_func, + free_func, run_func); + actions_register("DesktopRight", setup_go_right_func, + free_func, run_func); + actions_register("SendToDesktopRight", setup_send_right_func, + free_func, run_func); + actions_register("DesktopUp", setup_go_up_func, free_func, run_func); + actions_register("SendToDesktopUp", setup_send_up_func, + free_func, run_func); + actions_register("DesktopDown", setup_go_down_func, free_func, run_func); + actions_register("SendToDesktopDown", setup_send_down_func, + free_func, run_func); } -static gpointer setup_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_func(xmlNodePtr node) { xmlNodePtr n; Options *o; @@ -211,36 +142,12 @@ static gpointer setup_func(xmlNodePtr node, return o; } - -static gpointer setup_go_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) -{ - Options *o; - - o = setup_func(node, pre, input, cancel, post); - if (o->type == RELATIVE) { - o->interactive = TRUE; - *pre = i_pre_func; - *input = i_input_func; - *post = i_post_func; - } - - return o; -} - -static gpointer setup_send_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_send_func(xmlNodePtr node) { xmlNodePtr n; Options *o; - o = setup_func(node, pre, input, cancel, post); + o = setup_func(node); if ((n = obt_xml_find_node(node, "desktop"))) { /* 3.4 compatibility */ o->u.abs.desktop = obt_xml_node_int(n) - 1; @@ -252,13 +159,6 @@ static gpointer setup_send_func(xmlNodePtr node, if ((n = obt_xml_find_node(node, "follow"))) o->follow = obt_xml_node_bool(n); - if (o->type == RELATIVE && o->follow) { - o->interactive = TRUE; - *pre = i_pre_func; - *input = i_input_func; - *post = i_post_func; - } - return o; } @@ -310,62 +210,7 @@ static gboolean run_func(ObActionsData *data, gpointer options) actions_client_move(data, FALSE); } - return o->interactive; -} - -static gboolean i_input_func(guint initial_state, - XEvent *e, - ObtIC *ic, - gpointer options, - gboolean *used) -{ - guint mods, initial_mods; - - initial_mods = obt_keyboard_only_modmasks(initial_state); - mods = obt_keyboard_only_modmasks(e->xkey.state); - if (e->type == KeyRelease) { - /* remove from the state the mask of the modifier key being - released, if it is a modifier key being released that is */ - mods &= ~obt_keyboard_keyevent_to_modmask(e); - } - - if (e->type == KeyPress) { - KeySym sym = obt_keyboard_keypress_to_keysym(e); - - /* Escape cancels no matter what */ - if (sym == XK_Escape) - return FALSE; - - /* There were no modifiers and they pressed enter */ - else if ((sym == XK_Return || sym == XK_KP_Enter) && !initial_mods) - return FALSE; - } - /* They released the modifiers */ - else if (e->type == KeyRelease && initial_mods && !(mods & initial_mods)) - { - return FALSE; - } - - return TRUE; -} - -static gboolean i_pre_func(guint initial_state, gpointer options) -{ - guint initial_mods = obt_keyboard_only_modmasks(initial_state); - if (!initial_mods) { - Options *o = options; - o->interactive = FALSE; - return FALSE; - } - else { - screen_show_desktop_popup(screen_desktop, TRUE); - return TRUE; - } -} - -static void i_post_func(gpointer options) -{ - screen_hide_desktop_popup(); + return FALSE; } /* 3.4-compatilibity */ @@ -407,10 +252,7 @@ static gpointer setup_go_abs_func(xmlNodePtr node) } static void setup_rel(Options *o, xmlNodePtr node, gboolean lin, - ObDirection dir, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsIPostFunc *post) + ObDirection dir) { xmlNodePtr n; @@ -421,149 +263,88 @@ static void setup_rel(Options *o, xmlNodePtr node, gboolean lin, if ((n = obt_xml_find_node(node, "wrap"))) o->u.rel.wrap = obt_xml_node_bool(n); - - if (input) { - o->interactive = TRUE; - *pre = i_pre_func; - *input = i_input_func; - *post = i_post_func; - } } -static gpointer setup_go_next_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_go_next_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); - setup_rel(o, node, TRUE, OB_DIRECTION_EAST, pre, input, post); + setup_rel(o, node, TRUE, OB_DIRECTION_EAST); return o; } -static gpointer setup_send_next_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_send_next_func(xmlNodePtr node) { Options *o = setup_follow(node); - setup_rel(o, node, TRUE, OB_DIRECTION_EAST, - pre, (o->follow ? input : NULL), post); + setup_rel(o, node, TRUE, OB_DIRECTION_EAST); return o; } -static gpointer setup_go_prev_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_go_prev_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); - setup_rel(o, node, TRUE, OB_DIRECTION_WEST, pre, input, post); + setup_rel(o, node, TRUE, OB_DIRECTION_WEST); return o; } -static gpointer setup_send_prev_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_send_prev_func(xmlNodePtr node) { Options *o = setup_follow(node); - setup_rel(o, node, TRUE, OB_DIRECTION_WEST, - pre, (o->follow ? input : NULL), post); + setup_rel(o, node, TRUE, OB_DIRECTION_WEST); return o; } -static gpointer setup_go_left_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_go_left_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); - setup_rel(o, node, FALSE, OB_DIRECTION_WEST, pre, input, post); + setup_rel(o, node, FALSE, OB_DIRECTION_WEST); return o; } -static gpointer setup_send_left_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_send_left_func(xmlNodePtr node) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_WEST, - pre, (o->follow ? input : NULL), post); + setup_rel(o, node, FALSE, OB_DIRECTION_WEST); return o; } -static gpointer setup_go_right_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_go_right_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); - setup_rel(o, node, FALSE, OB_DIRECTION_EAST, pre, input, post); + setup_rel(o, node, FALSE, OB_DIRECTION_EAST); return o; } -static gpointer setup_send_right_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_send_right_func(xmlNodePtr node) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_EAST, - pre, (o->follow ? input : NULL), post); + setup_rel(o, node, FALSE, OB_DIRECTION_EAST); return o; } -static gpointer setup_go_up_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_go_up_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); - setup_rel(o, node, FALSE, OB_DIRECTION_NORTH, pre, input, post); + setup_rel(o, node, FALSE, OB_DIRECTION_NORTH); return o; } -static gpointer setup_send_up_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_send_up_func(xmlNodePtr node) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_NORTH, - pre, (o->follow ? input : NULL), post); + setup_rel(o, node, FALSE, OB_DIRECTION_NORTH); return o; } -static gpointer setup_go_down_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_go_down_func(xmlNodePtr node) { Options *o = g_slice_new0(Options); - setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH, pre, input, post); + setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH); return o; } -static gpointer setup_send_down_func(xmlNodePtr node, - ObActionsIPreFunc *pre, - ObActionsIInputFunc *input, - ObActionsICancelFunc *cancel, - ObActionsIPostFunc *post) +static gpointer setup_send_down_func(xmlNodePtr node) { Options *o = setup_follow(node); - setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH, - pre, (o->follow ? input : NULL), post); + setup_rel(o, node, FALSE, OB_DIRECTION_SOUTH); return o; } diff --git a/openbox/actions/growtoedge.c b/openbox/actions/growtoedge.c index d5a7bfdd..acfbcfab 100644 --- a/openbox/actions/growtoedge.c +++ b/openbox/actions/growtoedge.c @@ -8,9 +8,11 @@ typedef struct { ObDirection dir; gboolean shrink; + gboolean fill; } Options; -static gpointer setup_func(xmlNodePtr node); +static gpointer setup_grow_func(xmlNodePtr node); +static gpointer setup_fill_func(xmlNodePtr node); static gpointer setup_shrink_func(xmlNodePtr node); static void free_func(gpointer o); static gboolean run_func(ObActionsData *data, gpointer options); @@ -22,7 +24,9 @@ static gpointer setup_west_func(xmlNodePtr node); void action_growtoedge_startup(void) { - actions_register("GrowToEdge", setup_func, + actions_register("GrowToEdge", setup_grow_func, + free_func, run_func); + actions_register("GrowToFill", setup_fill_func, free_func, run_func); actions_register("ShrinkToEdge", setup_shrink_func, free_func, run_func); @@ -40,7 +44,6 @@ static gpointer setup_func(xmlNodePtr node) o = g_slice_new0(Options); o->dir = OB_DIRECTION_NORTH; - o->shrink = FALSE; if ((n = obt_xml_find_node(node, "direction"))) { gchar *s = obt_xml_node_string(n); @@ -62,12 +65,35 @@ static gpointer setup_func(xmlNodePtr node) return o; } +static gpointer setup_grow_func(xmlNodePtr node) +{ + Options *o; + + o = setup_func(node); + o->shrink = FALSE; + o->fill = FALSE; + + return o; +} + +static gpointer setup_fill_func(xmlNodePtr node) +{ + Options *o; + + o = setup_func(node); + o->shrink = FALSE; + o->fill = TRUE; + + return o; +} + static gpointer setup_shrink_func(xmlNodePtr node) { Options *o; o = setup_func(node); o->shrink = TRUE; + o->fill = FALSE; return o; } @@ -97,6 +123,58 @@ static gboolean do_grow(ObActionsData *data, gint x, gint y, gint w, gint h) return FALSE; } +static gboolean do_grow_all_edges(ObActionsData* data, + ObClientDirectionalResizeType resize_type) +{ + gint x, y, w, h; + gint temp_x, temp_y, temp_w, temp_h; + + client_find_resize_directional(data->client, + OB_DIRECTION_NORTH, + resize_type, + &temp_x, &temp_y, &temp_w, &temp_h); + y = temp_y; + h = temp_h; + + client_find_resize_directional(data->client, + OB_DIRECTION_SOUTH, + resize_type, + &temp_x, &temp_y, &temp_w, &temp_h); + h += temp_h - data->client->area.height; + + + client_find_resize_directional(data->client, + OB_DIRECTION_WEST, + resize_type, + &temp_x, &temp_y, &temp_w, &temp_h); + x = temp_x; + w = temp_w; + + client_find_resize_directional(data->client, + OB_DIRECTION_EAST, + resize_type, + &temp_x, &temp_y, &temp_w, &temp_h); + w += temp_w - data->client->area.width; + + /* When filling, we allow the window to move to an arbitrary x/y + position, since we'll be growing the other edge as well. */ + int lw, lh; + client_try_configure(data->client, &x, &y, &w, &h, &lw, &lh, TRUE); + + if (x == data->client->area.x && + y == data->client->area.y && + w == data->client->area.width && + h == data->client->area.height) + { + return FALSE; + } + + actions_client_move(data, TRUE); + client_move_resize(data->client, x, y, w, h); + actions_client_move(data, FALSE); + return TRUE; +} + static void free_func(gpointer o) { g_slice_free(Options, o); @@ -106,34 +184,62 @@ static void free_func(gpointer o) static gboolean run_func(ObActionsData *data, gpointer options) { Options *o = options; - gint x, y, w, h; - ObDirection opp; - gint half; - if (!data->client || - /* don't allow vertical resize if shaded */ - ((o->dir == OB_DIRECTION_NORTH || o->dir == OB_DIRECTION_SOUTH) && - data->client->shaded)) - { + if (!data->client) + return FALSE; + + gboolean doing_vertical_resize = + o->dir == OB_DIRECTION_NORTH || + o->dir == OB_DIRECTION_SOUTH || + o->fill; + if (data->client->shaded && doing_vertical_resize) + return FALSE; + + if (o->fill) { + if (o->shrink) { + /* We don't have any implementation of shrinking for the FillToGrow + action. */ + return FALSE; + } + + if (do_grow_all_edges(data, CLIENT_RESIZE_GROW_IF_NOT_ON_EDGE)) + return FALSE; + + /* If all the edges are blocked, then allow them to jump past their + current block points. */ + do_grow_all_edges(data, CLIENT_RESIZE_GROW); return FALSE; } if (!o->shrink) { - /* try grow */ - client_find_resize_directional(data->client, o->dir, TRUE, + gint x, y, w, h; + + /* Try grow. */ + client_find_resize_directional(data->client, + o->dir, + CLIENT_RESIZE_GROW, &x, &y, &w, &h); + if (do_grow(data, x, y, w, h)) return FALSE; } - /* we couldn't grow, so try shrink! */ - opp = (o->dir == OB_DIRECTION_NORTH ? OB_DIRECTION_SOUTH : - (o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH : - (o->dir == OB_DIRECTION_EAST ? OB_DIRECTION_WEST : - OB_DIRECTION_EAST))); - client_find_resize_directional(data->client, opp, FALSE, + /* We couldn't grow, so try shrink! */ + ObDirection opposite = + (o->dir == OB_DIRECTION_NORTH ? OB_DIRECTION_SOUTH : + (o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH : + (o->dir == OB_DIRECTION_EAST ? OB_DIRECTION_WEST : + OB_DIRECTION_EAST))); + + gint x, y, w, h; + gint half; + + client_find_resize_directional(data->client, + opposite, + CLIENT_RESIZE_SHRINK, &x, &y, &w, &h); - switch (opp) { + + switch (opposite) { case OB_DIRECTION_NORTH: half = data->client->area.y + data->client->area.height / 2; if (y > half) { diff --git a/openbox/actions/if.c b/openbox/actions/if.c index a083d485..a9c4094b 100644 --- a/openbox/actions/if.c +++ b/openbox/actions/if.c @@ -79,10 +79,9 @@ typedef struct { } Query; typedef struct { - GArray* queries; + GArray *queries; GSList *thenacts; GSList *elseacts; - gboolean stop; } Options; static gpointer setup_func(xmlNodePtr node); @@ -91,6 +90,8 @@ static gboolean run_func_if(ObActionsData *data, gpointer options); static gboolean run_func_stop(ObActionsData *data, gpointer options); static gboolean run_func_foreach(ObActionsData *data, gpointer options); +static gboolean foreach_stop; + void action_if_startup(void) { actions_register("If", setup_func, free_func, run_func_if); @@ -313,7 +314,7 @@ static gboolean run_func_if(ObActionsData *data, gpointer options) gboolean is_true = TRUE; guint i; - for (i = 0; i < o->queries->len; ++i) { + for (i = 0; is_true && i < o->queries->len; ++i) { Query *q = g_array_index(o->queries, Query*, i); ObClient *query_target = NULL; @@ -327,7 +328,10 @@ static gboolean run_func_if(ObActionsData *data, gpointer options) } /* If there's no client to query, then false. */ - is_true &= query_target != NULL; + if (!query_target) { + is_true = FALSE; + break; + } if (q->shaded_on) is_true &= query_target->shaded; @@ -427,14 +431,14 @@ static gboolean run_func_if(ObActionsData *data, gpointer options) static gboolean run_func_foreach(ObActionsData *data, gpointer options) { GList *it; - Options *o = options; - o->stop = FALSE; + foreach_stop = FALSE; for (it = client_list; it; it = g_list_next(it)) { data->client = it->data; run_func_if(data, options); - if (o->stop) { + if (foreach_stop) { + foreach_stop = FALSE; break; } } @@ -444,11 +448,9 @@ static gboolean run_func_foreach(ObActionsData *data, gpointer options) static gboolean run_func_stop(ObActionsData *data, gpointer options) { - Options *o = options; - /* This stops the loop above so we don't invoke actions on any more clients */ - o->stop = TRUE; + foreach_stop = TRUE; /* TRUE causes actions_run_acts to not run further actions on the current client */ diff --git a/openbox/actions/resize.c b/openbox/actions/resize.c index f6858d2d..fc85c0b7 100644 --- a/openbox/actions/resize.c +++ b/openbox/actions/resize.c @@ -2,6 +2,7 @@ #include "openbox/moveresize.h" #include "openbox/client.h" #include "openbox/frame.h" +#include "openbox/screen.h" #include "obt/prop.h" typedef struct { @@ -95,6 +96,12 @@ static gboolean run_func(ObActionsData *data, gpointer options) static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch, gboolean shaded) { + const Rect *full = screen_physical_area_all_monitors(); + if (cx < full->x) { cw = cw + cx - full->x; cx = full->x; } + if (cy < full->y) { ch = ch + cy - full->y; cy = full->y; } + if (cx + cw > full->x + full->width) cw = full->x + full->width - cx; + if (cy + ch > full->y + full->height) ch = full->y + full->height - cy; + /* 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 */ diff --git a/openbox/actions/showdesktop.c b/openbox/actions/showdesktop.c index 6dc77d5e..3c3b2d10 100644 --- a/openbox/actions/showdesktop.c +++ b/openbox/actions/showdesktop.c @@ -1,17 +1,52 @@ #include "openbox/actions.h" #include "openbox/screen.h" +typedef struct { + /* If true, windows are unable to be shown while in the showing-desktop + state. */ + gboolean strict; +} Options; + +static gpointer setup_func(xmlNodePtr node); +static void free_func(gpointer o); static gboolean run_func(ObActionsData *data, gpointer options); void action_showdesktop_startup(void) { - actions_register("ToggleShowDesktop", NULL, NULL, run_func); + actions_register("ToggleShowDesktop", setup_func, free_func, run_func); +} + +static gpointer setup_func(xmlNodePtr node) +{ + xmlNodePtr n; + Options *o = g_slice_new0(Options); + o->strict = FALSE; + + if ((n = obt_xml_find_node(node, "strict"))) + o->strict = obt_xml_node_bool(n); + + return o; +} + +static void free_func(gpointer o) +{ + g_slice_free(Options, o); } /* Always return FALSE because its not interactive */ static gboolean run_func(ObActionsData *data, gpointer options) { - screen_show_desktop(!screen_showing_desktop, NULL); + Options *o = options; + + ObScreenShowDestopMode show_mode; + if (screen_showing_desktop()) + show_mode = SCREEN_SHOW_DESKTOP_NO; + else if (!o->strict) + show_mode = SCREEN_SHOW_DESKTOP_UNTIL_WINDOW; + else + show_mode = SCREEN_SHOW_DESKTOP_UNTIL_TOGGLE; + + screen_show_desktop(show_mode, NULL); return FALSE; } diff --git a/openbox/actions/showmenu.c b/openbox/actions/showmenu.c index 485a31d5..7411e981 100644 --- a/openbox/actions/showmenu.c +++ b/openbox/actions/showmenu.c @@ -1,9 +1,17 @@ #include "openbox/actions.h" #include "openbox/menu.h" +#include "openbox/place.h" +#include "openbox/geom.h" +#include "openbox/screen.h" +#include "openbox/config.h" #include <glib.h> typedef struct { - gchar *name; + gchar *name; + GravityPoint position; + ObPlaceMonitor monitor_type; + gint monitor; + gboolean use_position; } Options; static gpointer setup_func(xmlNodePtr node); @@ -17,13 +25,50 @@ void action_showmenu_startup(void) static gpointer setup_func(xmlNodePtr node) { - xmlNodePtr n; + xmlNodePtr n, c; Options *o; + gboolean x_pos_given = FALSE; o = g_slice_new0(Options); + o->monitor = -1; if ((n = obt_xml_find_node(node, "menu"))) o->name = obt_xml_node_string(n); + + if ((n = obt_xml_find_node(node, "position"))) { + if ((c = obt_xml_find_node(n->children, "x"))) { + if (!obt_xml_node_contains(c, "default")) { + config_parse_gravity_coord(c, &o->position.x); + x_pos_given = TRUE; + } + } + + if (x_pos_given && (c = obt_xml_find_node(n->children, "y"))) { + if (!obt_xml_node_contains(c, "default")) { + config_parse_gravity_coord(c, &o->position.y); + o->use_position = TRUE; + } + } + + /* unlike client placement, x/y is needed to specify a monitor, + * either it's under the mouse or it's in an exact actual position */ + if (o->use_position && (c = obt_xml_find_node(n->children, "monitor"))) { + if (!obt_xml_node_contains(c, "default")) { + gchar *s = obt_xml_node_string(c); + if (!g_ascii_strcasecmp(s, "mouse")) + o->monitor_type = OB_PLACE_MONITOR_MOUSE; + else if (!g_ascii_strcasecmp(s, "active")) + o->monitor_type = OB_PLACE_MONITOR_ACTIVE; + else if (!g_ascii_strcasecmp(s, "primary")) + o->monitor_type = OB_PLACE_MONITOR_PRIMARY; + else if (!g_ascii_strcasecmp(s, "all")) + o->monitor_type = OB_PLACE_MONITOR_ALL; + else + o->monitor = obt_xml_node_int(c) - 1; + g_free(s); + } + } + } return o; } @@ -38,10 +83,43 @@ static void free_func(gpointer options) static gboolean run_func(ObActionsData *data, gpointer options) { Options *o = options; + GravityPoint position = { { 0, }, }; + gint monitor = -1; + + if (o->use_position) { + if (o->monitor >= 0) + monitor = o->monitor; + else switch (o->monitor_type) { + case OB_PLACE_MONITOR_ANY: + case OB_PLACE_MONITOR_PRIMARY: + monitor = screen_monitor_primary(FALSE); + break; + case OB_PLACE_MONITOR_MOUSE: + monitor = screen_monitor_pointer(); + break; + case OB_PLACE_MONITOR_ACTIVE: + monitor = screen_monitor_active(); + break; + case OB_PLACE_MONITOR_ALL: + monitor = screen_num_monitors; + break; + default: + g_assert_not_reached(); + } + + position = o->position; + } else { + const Rect *allmon; + monitor = screen_num_monitors; + allmon = screen_physical_area_monitor(monitor); + position.x.pos = data->x - allmon->x; + position.y.pos = data->y - allmon->y; + } /* you cannot call ShowMenu from inside a menu */ if (data->uact != OB_USER_ACTION_MENU_SELECTION && o->name) - menu_show(o->name, data->x, data->y, data->button != 0, data->client); + menu_show(o->name, &position, monitor, + data->button != 0, o->use_position, data->client); return FALSE; } |
