From: Dana Jansens Date: Wed, 3 Aug 2011 20:58:23 +0000 (-0400) Subject: Pass a client set to all actions, and make focus cycling use a client set. X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=a0454d46e64a73bb584cbc1bdb5ca9354f07ed3a;p=dana%2Fopenbox.git Pass a client set to all actions, and make focus cycling use a client set. --- diff --git a/openbox/action.c b/openbox/action.c index 36dca017..e134a652 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -280,6 +280,9 @@ gboolean action_run(ObAction *act, const ObActionListRun *data, If the action is doing something to the currently focused window, then we want to update its user_time to indicate it was used by a human now. + - However, we only do this for non-interactive actions, as we expect + them to do their "thing" on every window in the set. Interactive + actions generally let you choose one from a set to do stuff to. */ run_i = FALSE; @@ -304,15 +307,13 @@ gboolean action_run(ObAction *act, const ObActionListRun *data, if (run) { gboolean end; - /* XXX pass the set here */ - end = !act->def->run(data, act->options); + end = !act->def->run(set, data, act->options); g_assert(end || action_is_interactive(act)); if (end) { if (action_is_interactive(act)) action_interactive_end_act(); - /* XXX else if (client_set_contains(focus_client)) */ - else if (data->target && data->target == focus_client) + else if (client_set_contains(set, focus_client)) event_update_user_time(); } } diff --git a/openbox/action.h b/openbox/action.h index e6ec7de5..376540ec 100644 --- a/openbox/action.h +++ b/openbox/action.h @@ -33,7 +33,8 @@ typedef struct _ObAction ObAction; typedef struct _ObActionData ObActionData; typedef void (*ObActionDataFreeFunc)(gpointer options); -typedef gboolean (*ObActionRunFunc)(const struct _ObActionListRun *data, +typedef gboolean (*ObActionRunFunc)(const struct _ObClientSet *set, + const struct _ObActionListRun *data, gpointer options); typedef gpointer (*ObActionDataSetupFunc)(GHashTable *config); typedef void (*ObActionShutdownFunc)(void); diff --git a/openbox/action_list_run.c b/openbox/action_list_run.c index 3e912f06..3187d811 100644 --- a/openbox/action_list_run.c +++ b/openbox/action_list_run.c @@ -41,7 +41,6 @@ gboolean action_list_run(ObActionList *acts, { ObActionListRun action_data; - g_return_val_if_fail(acts != NULL, FALSE); if (acts == NULL) return FALSE; /* Don't save the initial mod state when running things from the menu */ diff --git a/openbox/actions/addremovedesktop.c b/openbox/actions/addremovedesktop.c index 22158daf..708086b4 100644 --- a/openbox/actions/addremovedesktop.c +++ b/openbox/actions/addremovedesktop.c @@ -1,6 +1,7 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/action_value.h" +#include "openbox/client_set.h" #include "openbox/screen.h" #include @@ -13,7 +14,8 @@ static gpointer setup_func(GHashTable *config); static gpointer setup_add_func(GHashTable *config); static gpointer setup_remove_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_addremovedesktop_startup(void) { @@ -62,7 +64,8 @@ static void free_func(gpointer o) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; diff --git a/openbox/actions/breakchroot.c b/openbox/actions/breakchroot.c index de2da715..e532f4c9 100644 --- a/openbox/actions/breakchroot.c +++ b/openbox/actions/breakchroot.c @@ -1,19 +1,20 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/keyboard.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_breakchroot_startup(void) { - action_register("BreakChroot", - OB_ACTION_DEFAULT_FILTER_EMPTY, - NULL, NULL, - run_func); + action_register("BreakChroot", OB_ACTION_DEFAULT_FILTER_EMPTY, + NULL, NULL, run_func); } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { /* break out of one chroot */ keyboard_reset_chains(1); diff --git a/openbox/actions/close.c b/openbox/actions/close.c index eb9db51b..5feb7d46 100644 --- a/openbox/actions/close.c +++ b/openbox/actions/close.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/client.h" +#include "openbox/client_set.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_close_startup(void) { @@ -10,10 +12,22 @@ void action_close_startup(void) NULL, NULL, run_func); } +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_close(c); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) client_close(data->target); + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_run, options); + action_client_move(data, FALSE); + } return FALSE; } diff --git a/openbox/actions/cyclewindows.c b/openbox/actions/cyclewindows.c index 0087f8d5..3a0bd8a8 100644 --- a/openbox/actions/cyclewindows.c +++ b/openbox/actions/cyclewindows.c @@ -3,6 +3,7 @@ #include "openbox/action_list_run.h" #include "openbox/action_parser.h" #include "openbox/action_value.h" +#include "openbox/client_set.h" #include "openbox/stacking.h" #include "openbox/window.h" #include "openbox/event.h" @@ -15,8 +16,6 @@ typedef struct { gboolean linear; gboolean dock_windows; gboolean desktop_windows; - gboolean only_hilite_windows; - gboolean all_desktops; gboolean forward; gboolean bar; gboolean raise; @@ -45,7 +44,8 @@ static gpointer setup_backward_func(GHashTable *config, ObActionICancelFunc *c, ObActionIPostFunc *post); static void free_func(gpointer options); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); static gboolean i_input_func(guint initial_state, XEvent *e, ObtIC *ic, @@ -97,15 +97,9 @@ static gpointer setup_func(GHashTable *config, v = g_hash_table_lookup(config, "panels"); if (v && action_value_is_string(v)) o->dock_windows = action_value_bool(v); - v = g_hash_table_lookup(config, "hilite"); - if (v && action_value_is_string(v)) - o->only_hilite_windows = action_value_bool(v); v = g_hash_table_lookup(config, "desktop"); if (v && action_value_is_string(v)) o->desktop_windows = action_value_bool(v); - v = g_hash_table_lookup(config, "allDesktops"); - if (v && action_value_is_string(v)) - o->all_desktops = action_value_bool(v); v = g_hash_table_lookup(config, "finalactions"); if (v && action_value_is_action_list(v)) { @@ -157,14 +151,16 @@ static void free_func(gpointer options) g_slice_free(Options, o); } -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; struct _ObClient *ft; - ft = focus_cycle(o->forward, - o->all_desktops, - !o->only_hilite_windows, + if (client_set_is_empty(set)) return FALSE; + + ft = focus_cycle(set, + o->forward, o->dock_windows, o->desktop_windows, o->linear, @@ -235,9 +231,8 @@ static void i_post_func(gpointer options) Options *o = options; struct _ObClient *ft; - ft = focus_cycle(o->forward, - o->all_desktops, - !o->only_hilite_windows, + ft = focus_cycle(NULL, + o->forward, o->dock_windows, o->desktop_windows, o->linear, diff --git a/openbox/actions/debug.c b/openbox/actions/debug.c index 74e47232..9f194958 100644 --- a/openbox/actions/debug.c +++ b/openbox/actions/debug.c @@ -1,6 +1,7 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/action_value.h" +#include "openbox/client_set.h" #include typedef struct { @@ -9,7 +10,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer options); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_debug_startup(void) { @@ -38,7 +40,8 @@ static void free_func(gpointer options) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; diff --git a/openbox/actions/decorations.c b/openbox/actions/decorations.c index 05e6e1b6..037b9d57 100644 --- a/openbox/actions/decorations.c +++ b/openbox/actions/decorations.c @@ -1,10 +1,14 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/client.h" +#include "openbox/client_set.h" -static gboolean run_func_on(const ObActionListRun *data, gpointer options); -static gboolean run_func_off(const ObActionListRun *data, gpointer options); -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options); +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_decorations_startup(void) { @@ -16,34 +20,55 @@ void action_decorations_startup(void) NULL, NULL, run_func_toggle); } +static gboolean each_on(ObClient *c, const ObActionListRun *data, gpointer o) +{ + client_set_undecorated(data->target, FALSE); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_on(const ObActionListRun *data, gpointer options) +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_set_undecorated(data->target, FALSE); + client_set_run(set, data, each_on, options); action_client_move(data, FALSE); } return FALSE; } +static gboolean each_off(ObClient *c, const ObActionListRun *data, gpointer o) +{ + client_set_undecorated(data->target, TRUE); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_off(const ObActionListRun *data, gpointer options) +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_set_undecorated(data->target, TRUE); + client_set_run(set, data, each_off, options); action_client_move(data, FALSE); } return FALSE; } +static gboolean each_flip(ObClient *c, const ObActionListRun *data, gpointer o) +{ + client_set_undecorated(data->target, !c->undecorated); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options) +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_set_undecorated(data->target, !data->target->undecorated); + client_set_run(set, data, each_flip, options); action_client_move(data, FALSE); } return FALSE; diff --git a/openbox/actions/desktop.c b/openbox/actions/desktop.c index 185e039b..b04ce3be 100644 --- a/openbox/actions/desktop.c +++ b/openbox/actions/desktop.c @@ -3,6 +3,7 @@ #include "openbox/action_value.h" #include "openbox/screen.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/openbox.h" #include "obt/keyboard.h" @@ -29,6 +30,10 @@ typedef struct { gboolean send; gboolean follow; gboolean interactive; + + /* for the foreach function */ + guint d; + GSList *moved; } Options; static gpointer setup_go_func(GHashTable *config, @@ -42,7 +47,8 @@ static gpointer setup_send_func(GHashTable *config, ObActionICancelFunc *cancel, ObActionIPostFunc *post); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); static gboolean i_pre_func(guint state, gpointer options); static gboolean i_input_func(guint initial_state, @@ -179,7 +185,19 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_send(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + Options *o = options; + if (client_normal(c)) { + client_set_desktop(c, o->d, o->follow, FALSE); + o->moved = g_slist_prepend(o->moved, c); + } + return TRUE; +} + +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; guint d; @@ -202,22 +220,28 @@ static gboolean run_func(const ObActionListRun *data, gpointer options) g_assert_not_reached(); } - if (d < screen_num_desktops && - (d != screen_desktop || - (data->target && data->target->desktop != screen_desktop))) { - gboolean go = TRUE; + if (d < screen_num_desktops) { + gboolean go; + + go = TRUE; + o->d = d; + o->moved = NULL; action_client_move(data, TRUE); - if (o->send && data->target && client_normal(data->target)) { - client_set_desktop(data->target, d, o->follow, FALSE); + if (o->send) { + client_set_run(set, data, each_send, o); go = o->follow; } if (go) { - screen_set_desktop(d, TRUE); - if (data->target) - client_bring_helper_windows(data->target); + GSList *it; + + if (d != screen_desktop) + screen_set_desktop(d, TRUE); + for (it = o->moved; it; it = g_slist_next(it)) + client_bring_helper_windows(it->data); } + g_slist_free(o->moved); action_client_move(data, FALSE); } diff --git a/openbox/actions/directionalwindows.c b/openbox/actions/directionalwindows.c index e62e9b7f..17b57c0a 100644 --- a/openbox/actions/directionalwindows.c +++ b/openbox/actions/directionalwindows.c @@ -3,6 +3,7 @@ #include "openbox/action_list_run.h" #include "openbox/action_parser.h" #include "openbox/action_value.h" +#include "openbox/client_set.h" #include "openbox/event.h" #include "openbox/stacking.h" #include "openbox/window.h" @@ -33,7 +34,8 @@ static gpointer setup_cycle_func(GHashTable *config, ObActionIPostFunc *post); static gpointer setup_target_func(GHashTable *config); static void free_func(gpointer options); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); static gboolean i_input_func(guint initial_state, XEvent *e, ObtIC *ic, @@ -145,16 +147,20 @@ static void free_func(gpointer options) g_slice_free(Options, o); } -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; + if (client_set_is_empty(set)) return FALSE; + if (!o->interactive) end_cycle(FALSE, data->mod_state, o); else { struct _ObClient *ft; ft = focus_directional_cycle(o->direction, + set, o->dock_windows, o->desktop_windows, TRUE, @@ -223,6 +229,7 @@ static void end_cycle(gboolean cancel, guint state, Options *o) struct _ObClient *ft; ft = focus_directional_cycle(o->direction, + NULL, o->dock_windows, o->desktop_windows, o->interactive, diff --git a/openbox/actions/dock.c b/openbox/actions/dock.c index d3aa2258..f555ec94 100644 --- a/openbox/actions/dock.c +++ b/openbox/actions/dock.c @@ -1,11 +1,14 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/stacking.h" #include "openbox/window.h" #include "openbox/dock.h" -static gboolean raise_func(const ObActionListRun *data, gpointer options); -static gboolean lower_func(const ObActionListRun *data, gpointer options); +static gboolean raise_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean lower_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_dock_startup(void) { @@ -16,7 +19,8 @@ void action_dock_startup(void) } /* Always return FALSE because its not interactive */ -static gboolean raise_func(const ObActionListRun *data, gpointer options) +static gboolean raise_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { action_client_move(data, TRUE); dock_raise_dock(); @@ -26,7 +30,8 @@ static gboolean raise_func(const ObActionListRun *data, gpointer options) } /* Always return FALSE because its not interactive */ -static gboolean lower_func(const ObActionListRun *data, gpointer options) +static gboolean lower_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { action_client_move(data, TRUE); dock_lower_dock(); diff --git a/openbox/actions/dockautohide.c b/openbox/actions/dockautohide.c index 6b31d873..e21d8092 100644 --- a/openbox/actions/dockautohide.c +++ b/openbox/actions/dockautohide.c @@ -1,9 +1,11 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" -#include "openbox/dock.h" +#include "openbox/client_set.h" #include "openbox/config.h" +#include "openbox/dock.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_dockautohide_startup(void) { @@ -12,10 +14,13 @@ void action_dockautohide_startup(void) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { config_dock_hide = !config_dock_hide; + action_client_move(data, TRUE); dock_configure(); + action_client_move(data, FALSE); return FALSE; } diff --git a/openbox/actions/execute.c b/openbox/actions/execute.c index 22879bcc..e4f99dd2 100644 --- a/openbox/actions/execute.c +++ b/openbox/actions/execute.c @@ -1,11 +1,12 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/action_value.h" -#include "openbox/event.h" -#include "openbox/startupnotify.h" #include "openbox/client.h" +#include "openbox/client_set.h" +#include "openbox/event.h" #include "openbox/prompt.h" #include "openbox/screen.h" +#include "openbox/startupnotify.h" #include "obt/paths.h" #include "gettext.h" @@ -20,12 +21,16 @@ typedef struct { gchar *sn_icon; gchar *sn_wmclass; gchar *prompt; + + /* for the prompt callback */ ObActionListRun *data; + ObClientSet *set; } Options; static gpointer setup_func(GHashTable *config); static void free_func(gpointer options); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); static void shutdown_func(void); static void client_dest(ObClient *client, gpointer data); @@ -99,12 +104,14 @@ static void free_func(gpointer options) g_free(o->sn_icon); g_free(o->sn_wmclass); g_free(o->prompt); + if (o->set) client_set_destroy(o->set); if (o->data) g_slice_free(ObActionListRun, o->data); g_slice_free(Options, o); } } -static Options* dup_options(Options *in, const ObActionListRun *data) +static Options* dup_options(Options *in, const ObClientSet *set, + const ObActionListRun *data) { Options *o = g_slice_new(Options); o->cmd = g_strdup(in->cmd); @@ -113,50 +120,19 @@ static Options* dup_options(Options *in, const ObActionListRun *data) o->sn_icon = g_strdup(in->sn_icon); o->sn_wmclass = g_strdup(in->sn_wmclass); o->prompt = NULL; + o->set = client_set_clone(set); o->data = g_slice_new(ObActionListRun); memcpy(o->data, data, sizeof(ObActionListRun)); return o; } -static gboolean prompt_cb(ObPrompt *p, gint result, gpointer options) +static gboolean do_execute_each(ObClient *client, + const ObActionListRun *data, gpointer options) { Options *o = options; - if (result) - run_func(o->data, o); - return TRUE; /* call the cleanup func */ -} - -static void prompt_cleanup(ObPrompt *p, gpointer options) -{ - prompt_unref(p); - free_func(options); -} - -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) -{ GError *e; gchar **argv = NULL; gchar *cmd; - Options *o = options; - - if (!o->cmd) return FALSE; - - if (o->prompt) { - ObPrompt *p; - Options *ocp; - ObPromptAnswer answers[] = { - { _("No"), 0 }, - { _("Yes"), 1 } - }; - - ocp = dup_options(options, data); - p = prompt_new(o->prompt, _("Execute"), answers, 2, 0, 0, - prompt_cb, prompt_cleanup, ocp); - prompt_show(p, NULL, FALSE); - - return FALSE; - } cmd = g_filename_from_utf8(o->cmd, -1, NULL, NULL, NULL); if (!cmd) { @@ -164,7 +140,7 @@ static gboolean run_func(const ObActionListRun *data, gpointer options) return FALSE; } - if (data->target) { + if (client) { gchar *c, *before, *expand; /* replace occurrences of $pid and $wid */ @@ -186,7 +162,7 @@ static gboolean run_func(const ObActionListRun *data, gpointer options) expand = g_strdup_printf("%s%s%u", (expand ? expand : ""), before, - data->target->pid); + client->pid); g_free(tmp); before = c + 4; /* 4 = strlen("$pid") */ @@ -204,7 +180,7 @@ static gboolean run_func(const ObActionListRun *data, gpointer options) expand = g_strdup_printf("%s%s%lu", (expand ? expand : ""), before, - data->target->window); + client->window); g_free(tmp); before = c + 4; /* 4 = strlen("$wid") */ @@ -271,5 +247,57 @@ static gboolean run_func(const ObActionListRun *data, gpointer options) g_free(cmd); + return TRUE; +} + +/* Always return FALSE because its not interactive */ +static gboolean do_execute(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (client_set_is_empty(set)) + do_execute_each(NULL, data, options); + else + client_set_run(set, data, do_execute_each, options); return FALSE; } + +static gboolean prompt_cb(ObPrompt *p, gint result, gpointer options) +{ + Options *o = options; + if (result) + run_func(o->set, o->data, o); + return TRUE; /* call the cleanup func */ +} + +static void prompt_cleanup(ObPrompt *p, gpointer options) +{ + prompt_unref(p); + free_func(options); +} + +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + Options *o = options; + + if (!o->cmd) return FALSE; + + if (o->prompt) { + ObPrompt *p; + Options *ocp; + ObPromptAnswer answers[] = { + { _("No"), 0 }, + { _("Yes"), 1 } + }; + + ocp = dup_options(options, set, data); + p = prompt_new(o->prompt, _("Execute"), answers, 2, 0, 0, + prompt_cb, prompt_cleanup, ocp); + prompt_show(p, NULL, FALSE); + + return FALSE; + } + + return do_execute(set, data, options); +} diff --git a/openbox/actions/exit.c b/openbox/actions/exit.c index 5be209e3..ae061e15 100644 --- a/openbox/actions/exit.c +++ b/openbox/actions/exit.c @@ -1,6 +1,7 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/action_value.h" +#include "openbox/client_set.h" #include "openbox/openbox.h" #include "openbox/prompt.h" #include "openbox/session.h" @@ -12,7 +13,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_exit_startup(void) { @@ -62,7 +64,8 @@ static void prompt_cleanup(ObPrompt *p, gpointer data) /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; diff --git a/openbox/actions/focus.c b/openbox/actions/focus.c index f1e6f292..64af985c 100644 --- a/openbox/actions/focus.c +++ b/openbox/actions/focus.c @@ -3,6 +3,7 @@ #include "openbox/action_value.h" #include "openbox/event.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/focus.h" #include "openbox/screen.h" @@ -13,7 +14,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_focus_startup(void) { @@ -43,38 +45,50 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_focus(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; - if (data->target) { /* - ob_debug("button %d focusable %d context %d %d %d\n", - data->button, client_mouse_focusable(data->client), - data->context, - OB_FRAME_CONTEXT_CLIENT, OB_FRAME_CONTEXT_FRAME); + ob_debug("button %d focusable %d context %d %d %d\n", + data->button, client_mouse_focusable(data->client), + data->context, + OB_FRAME_CONTEXT_CLIENT, OB_FRAME_CONTEXT_FRAME); */ - if (data->pointer_button == 0 || - client_mouse_focusable(data->target) || - (data->pointer_context != OB_FRAME_CONTEXT_CLIENT && - data->pointer_context != OB_FRAME_CONTEXT_FRAME)) - { - if (o->stop_int) - action_interactive_cancel_act(); - - action_client_move(data, TRUE); - client_activate(data->target, TRUE, o->here, FALSE, FALSE, TRUE); - action_client_move(data, FALSE); - } - } else if (data->pointer_context == OB_FRAME_CONTEXT_DESKTOP) { + if (data->pointer_button == 0 || + client_mouse_focusable(c) || + (data->pointer_context != OB_FRAME_CONTEXT_CLIENT && + data->pointer_context != OB_FRAME_CONTEXT_FRAME)) + { if (o->stop_int) action_interactive_cancel_act(); + client_activate(c, TRUE, o->here, FALSE, FALSE, TRUE); + } + + return FALSE; /* only do this to one client */ +} + +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + Options *o = options; + + if (client_set_is_empty(set)) { + if (data->pointer_context == OB_FRAME_CONTEXT_DESKTOP) + if (o->stop_int) + action_interactive_cancel_act(); + /* focus action on the root window. make keybindings work for this openbox instance, but don't focus any specific client */ focus_nothing(); } - + else { + action_client_move(data, TRUE); + client_set_run(set, data, each_focus, options); + action_client_move(data, FALSE); + } return FALSE; } diff --git a/openbox/actions/focustobottom.c b/openbox/actions/focustobottom.c index 942d7887..ea168ae3 100644 --- a/openbox/actions/focustobottom.c +++ b/openbox/actions/focustobottom.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/focus.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_focustobottom_startup(void) { @@ -10,10 +12,17 @@ void action_focustobottom_startup(void) NULL, NULL, run_func); } +static gboolean each_run(struct _ObClient *c, const ObActionListRun *data, + gpointer options) +{ + focus_order_to_bottom(c); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) - focus_order_to_bottom(data->target); + client_set_run(set, data, each_run, options); return FALSE; } diff --git a/openbox/actions/fullscreen.c b/openbox/actions/fullscreen.c index 68f0738d..1abc3cbb 100644 --- a/openbox/actions/fullscreen.c +++ b/openbox/actions/fullscreen.c @@ -1,21 +1,73 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/client.h" +#include "openbox/client_set.h" -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options); +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_fullscreen_startup(void) { + action_register("Fullscreen", OB_ACTION_DEFAULT_FILTER_SINGLE, + NULL, NULL, run_func_on); + action_register("Unfullscreen", OB_ACTION_DEFAULT_FILTER_SINGLE, + NULL, NULL, run_func_off); action_register("ToggleFullscreen", OB_ACTION_DEFAULT_FILTER_SINGLE, NULL, NULL, run_func_toggle); } +static gboolean each_on(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_fullscreen(c, TRUE); + return TRUE; +} + +/* Always return FALSE because its not interactive */ +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + action_client_move(data, TRUE); + client_set_run(set, data, each_on, options); + action_client_move(data, FALSE); + return FALSE; +} + +static gboolean each_off(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_fullscreen(c, FALSE); + return TRUE; +} + +/* Always return FALSE because its not interactive */ +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + action_client_move(data, TRUE); + client_set_run(set, data, each_off, options); + action_client_move(data, FALSE); + return FALSE; +} + +static gboolean each_toggle(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_fullscreen(c, !c->fullscreen); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options) +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_fullscreen(data->target, !data->target->fullscreen); + client_set_run(set, data, each_toggle, options); action_client_move(data, FALSE); } return FALSE; diff --git a/openbox/actions/growtoedge.c b/openbox/actions/growtoedge.c index 7bfebe10..55f6a90c 100644 --- a/openbox/actions/growtoedge.c +++ b/openbox/actions/growtoedge.c @@ -3,6 +3,7 @@ #include "openbox/action_value.h" #include "openbox/misc.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/frame.h" #include "openbox/screen.h" #include @@ -15,7 +16,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static gpointer setup_shrink_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_growtoedge_startup(void) { @@ -81,9 +83,7 @@ static gboolean do_grow(const ObActionListRun *data, gint x, gint y, gint w, gin realw != data->target->area.width || realh != data->target->area.height) { - action_client_move(data, TRUE); client_move_resize(data->target, x, y, realw, realh); - action_client_move(data, FALSE); return TRUE; } return FALSE; @@ -94,28 +94,27 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_run(ObClient *c, + const ObActionListRun *data, gpointer options) { Options *o = options; gint x, y, w, h; ObDirection opp; gint half; - if (!data->target || + if (!c || /* don't allow vertical resize if shaded */ ((o->dir == OB_DIRECTION_NORTH || o->dir == OB_DIRECTION_SOUTH) && - data->target->shaded)) + c->shaded)) { - return FALSE; + return TRUE; } if (!o->shrink) { /* try grow */ - client_find_resize_directional(data->target, o->dir, TRUE, - &x, &y, &w, &h); + client_find_resize_directional(c, o->dir, TRUE, &x, &y, &w, &h); if (do_grow(data, x, y, w, h)) - return FALSE; + return TRUE; } /* we couldn't grow, so try shrink! */ @@ -123,37 +122,48 @@ static gboolean run_func(const ObActionListRun *data, gpointer options) (o->dir == OB_DIRECTION_SOUTH ? OB_DIRECTION_NORTH : (o->dir == OB_DIRECTION_EAST ? OB_DIRECTION_WEST : OB_DIRECTION_EAST))); - client_find_resize_directional(data->target, opp, FALSE, - &x, &y, &w, &h); + client_find_resize_directional(c, opp, FALSE, &x, &y, &w, &h); switch (opp) { case OB_DIRECTION_NORTH: - half = data->target->area.y + data->target->area.height / 2; + half = c->area.y + c->area.height / 2; if (y > half) { h += y - half; y = half; } break; case OB_DIRECTION_SOUTH: - half = data->target->area.height / 2; + half = c->area.height / 2; if (h < half) h = half; break; case OB_DIRECTION_WEST: - half = data->target->area.x + data->target->area.width / 2; + half = c->area.x + c->area.width / 2; if (x > half) { w += x - half; x = half; } break; case OB_DIRECTION_EAST: - half = data->target->area.width / 2; + half = c->area.width / 2; if (w < half) w = half; break; default: g_assert_not_reached(); } if (do_grow(data, x, y, w, h)) - return FALSE; + return TRUE; + + return TRUE; +} +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_run, options); + action_client_move(data, FALSE); + } return FALSE; } diff --git a/openbox/actions/iconify.c b/openbox/actions/iconify.c index fddf8f9d..da0942e8 100644 --- a/openbox/actions/iconify.c +++ b/openbox/actions/iconify.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/client.h" +#include "openbox/client_set.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_iconify_startup(void) { @@ -10,14 +12,21 @@ void action_iconify_startup(void) NULL, NULL, run_func); } +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_iconify(c, TRUE, TRUE, FALSE); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_iconify(data->target, TRUE, TRUE, FALSE); + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); } - return FALSE; } diff --git a/openbox/actions/kill.c b/openbox/actions/kill.c index f3f39539..f428c797 100644 --- a/openbox/actions/kill.c +++ b/openbox/actions/kill.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/client.h" +#include "openbox/client_set.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_kill_startup(void) { @@ -10,11 +12,21 @@ void action_kill_startup(void) NULL, NULL, run_func); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) { - if (data->target) - client_kill(data->target); + client_kill(c); + return TRUE; +} +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_run, options); + action_client_move(data, FALSE); + } return FALSE; } diff --git a/openbox/actions/layer.c b/openbox/actions/layer.c index 646f20d2..8da56446 100644 --- a/openbox/actions/layer.c +++ b/openbox/actions/layer.c @@ -2,6 +2,7 @@ #include "openbox/action_list_run.h" #include "openbox/action_value.h" #include "openbox/client.h" +#include "openbox/client_set.h" typedef struct { gint layer; /*!< -1 for below, 0 for normal, and 1 for above */ @@ -12,7 +13,8 @@ static gpointer setup_func_top(GHashTable *config); static gpointer setup_func_bottom(GHashTable *config); static gpointer setup_func_send(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_layer_startup(void) { @@ -69,29 +71,32 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; - if (data->target) { - ObClient *c = data->target; + if (o->layer < 0) { + if (o->toggle || !c->below) + client_set_layer(c, c->below ? 0 : -1); + } + else if (o->layer > 0) { + if (o->toggle || !c->above) + client_set_layer(c, c->above ? 0 : 1); + } + else if (c->above || c->below) + client_set_layer(c, 0); + return TRUE; +} +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - - if (o->layer < 0) { - if (o->toggle || !c->below) - client_set_layer(c, c->below ? 0 : -1); - } - else if (o->layer > 0) { - if (o->toggle || !c->above) - client_set_layer(c, c->above ? 0 : 1); - } - else if (c->above || c->below) - client_set_layer(c, 0); - + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); } - return FALSE; } diff --git a/openbox/actions/lower.c b/openbox/actions/lower.c index a95a2829..f2acc1a1 100644 --- a/openbox/actions/lower.c +++ b/openbox/actions/lower.c @@ -1,9 +1,11 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/stacking.h" #include "openbox/window.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_lower_startup(void) { @@ -11,12 +13,20 @@ void action_lower_startup(void) NULL, NULL, run_func); } +static gboolean each_run(struct _ObClient *c, const ObActionListRun *data, + gpointer options) +{ + stacking_lower(CLIENT_AS_WINDOW(c)); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - stacking_lower(CLIENT_AS_WINDOW(data->target)); + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); } diff --git a/openbox/actions/maximize.c b/openbox/actions/maximize.c index 71c67e54..325a4fe4 100644 --- a/openbox/actions/maximize.c +++ b/openbox/actions/maximize.c @@ -2,6 +2,7 @@ #include "openbox/action_list_run.h" #include "openbox/action_value.h" #include "openbox/client.h" +#include "openbox/client_set.h" /* These match the values for client_maximize */ typedef enum { @@ -16,9 +17,12 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func_on(const ObActionListRun *data, gpointer options); -static gboolean run_func_off(const ObActionListRun *data, gpointer options); -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options); +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_maximize_startup(void) { @@ -57,8 +61,8 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func_on(const ObActionListRun *data, gpointer options) +static gboolean each_on(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; if (data->target) { @@ -66,11 +70,23 @@ static gboolean run_func_on(const ObActionListRun *data, gpointer options) client_maximize(data->target, TRUE, o->dir); action_client_move(data, FALSE); } - return FALSE; + return TRUE; } /* Always return FALSE because its not interactive */ -static gboolean run_func_off(const ObActionListRun *data, gpointer options) +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_on, options); + action_client_move(data, FALSE); + } + return FALSE; +} + +static gboolean each_off(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; if (data->target) { @@ -78,21 +94,41 @@ static gboolean run_func_off(const ObActionListRun *data, gpointer options) client_maximize(data->target, FALSE, o->dir); action_client_move(data, FALSE); } - return FALSE; + return TRUE; } /* Always return FALSE because its not interactive */ -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options) +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_off, options); + action_client_move(data, FALSE); + } + return FALSE; +} + +static gboolean each_toggle(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; - if (data->target) { - gboolean toggle; + gboolean toggle; + toggle = ((o->dir == HORZ && !data->target->max_horz) || + (o->dir == VERT && !data->target->max_vert) || + (o->dir == BOTH && + !(data->target->max_horz && data->target->max_vert))); + client_maximize(data->target, toggle, o->dir); + return TRUE; +} + +/* Always return FALSE because its not interactive */ +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - toggle = ((o->dir == HORZ && !data->target->max_horz) || - (o->dir == VERT && !data->target->max_vert) || - (o->dir == BOTH && - !(data->target->max_horz && data->target->max_vert))); - client_maximize(data->target, toggle, o->dir); + client_set_run(set, data, each_toggle, options); action_client_move(data, FALSE); } return FALSE; diff --git a/openbox/actions/move.c b/openbox/actions/move.c index 883fe71a..bef6a75f 100644 --- a/openbox/actions/move.c +++ b/openbox/actions/move.c @@ -1,9 +1,12 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/moveresize.h" #include "obt/prop.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_move_startup(void) { @@ -12,18 +15,25 @@ void action_move_startup(void) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { - guint32 corner; + GList *list; + guint32 corner; + ObClient *c; - corner = data->pointer_button != 0 ? - OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE) : - OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD); + /* XXX only works on sets of size 1 right now until moveresize changes */ + if (client_set_size(set) != 1) return FALSE; - moveresize_start(data->target, data->pointer_x, data->pointer_y, - data->pointer_button, corner); - } + list = client_set_get_all(set); + c = list->data; + g_list_free(list); + corner = data->pointer_button != 0 ? + OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE) : + OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD); + + moveresize_start(c, data->pointer_x, data->pointer_y, + data->pointer_button, corner); return FALSE; } diff --git a/openbox/actions/moverelative.c b/openbox/actions/moverelative.c index 36504b09..9a05bfcd 100644 --- a/openbox/actions/moverelative.c +++ b/openbox/actions/moverelative.c @@ -2,6 +2,7 @@ #include "openbox/action_list_run.h" #include "openbox/action_value.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/screen.h" #include "openbox/frame.h" #include "openbox/config.h" @@ -15,7 +16,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_moverelative_startup(void) { @@ -45,38 +47,41 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; + gint x, y, lw, lh, w, h; - if (data->target) { - ObClient *c; - gint x, y, lw, lh, w, h; - - c = data->target; - x = o->x; - y = o->y; - if (o->x_denom || o->y_denom) { - const Rect *carea; + x = o->x; + y = o->y; + if (o->x_denom || o->y_denom) { + const Rect *carea; - carea = screen_area(c->desktop, client_monitor(c), NULL); - if (o->x_denom) - x = (x * carea->width) / o->x_denom; - if (o->y_denom) - y = (y * carea->height) / o->y_denom; - } - x = c->area.x + x; - y = c->area.y + y; - w = c->area.width; - h = c->area.height; - client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE); - client_find_onscreen(c, &x, &y, w, h, FALSE); + carea = screen_area(c->desktop, client_monitor(c), NULL); + if (o->x_denom) + x = (x * carea->width) / o->x_denom; + if (o->y_denom) + y = (y * carea->height) / o->y_denom; + } + x = c->area.x + x; + y = c->area.y + y; + w = c->area.width; + h = c->area.height; + client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE); + client_find_onscreen(c, &x, &y, w, h, FALSE); + client_configure(c, x, y, w, h, TRUE, TRUE, FALSE); + return TRUE; +} +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_configure(c, x, y, w, h, TRUE, TRUE, FALSE); + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); } - return FALSE; } diff --git a/openbox/actions/moveresizeto.c b/openbox/actions/moveresizeto.c index 06acd2dd..03f1c75e 100644 --- a/openbox/actions/moveresizeto.c +++ b/openbox/actions/moveresizeto.c @@ -2,6 +2,7 @@ #include "openbox/action_list_run.h" #include "openbox/action_value.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/screen.h" #include "openbox/frame.h" #include "openbox/config.h" @@ -25,7 +26,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_moveresizeto_startup(void) { @@ -84,86 +86,90 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; + Rect *area, *carea; + guint mon, cmon; + gint x, y, lw, lh, w, h; + + mon = o->monitor; + cmon = client_monitor(c); + switch (mon) { + case CURRENT_MONITOR: + mon = cmon; break; + case ALL_MONITORS: + mon = SCREEN_AREA_ALL_MONITORS; break; + case NEXT_MONITOR: + mon = (cmon + 1 > screen_num_monitors - 1) ? 0 : (cmon + 1); break; + case PREV_MONITOR: + mon = (cmon == 0) ? (screen_num_monitors - 1) : (cmon - 1); break; + default: + g_assert_not_reached(); + } - if (data->target) { - Rect *area, *carea; - ObClient *c; - guint mon, cmon; - gint x, y, lw, lh, w, h; - - c = data->target; - mon = o->monitor; - cmon = client_monitor(c); - switch (mon) { - case CURRENT_MONITOR: - mon = cmon; break; - case ALL_MONITORS: - mon = SCREEN_AREA_ALL_MONITORS; break; - case NEXT_MONITOR: - mon = (cmon + 1 > screen_num_monitors - 1) ? 0 : (cmon + 1); break; - case PREV_MONITOR: - mon = (cmon == 0) ? (screen_num_monitors - 1) : (cmon - 1); break; - default: - g_assert_not_reached(); - } - - area = screen_area(c->desktop, mon, NULL); - carea = screen_area(c->desktop, cmon, NULL); - - w = o->w; - if (w == G_MININT) w = c->area.width; - else if (o->w_denom) w = (w * area->width) / o->w_denom; - - h = o->h; - if (h == G_MININT) h = c->area.height; - else if (o->h_denom) h = (h * area->height) / o->h_denom; - - /* it might not be able to resize how they requested, so find out what - it will actually be resized to */ - x = c->area.x; - y = c->area.y; - client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE); - - /* get the frame's size */ - w += c->frame->size.left + c->frame->size.right; - h += c->frame->size.top + c->frame->size.bottom; - - x = o->x.pos; - if (o->x.denom) - x = (x * area->width) / o->x.denom; - if (o->x.center) x = (area->width - w) / 2; - else if (x == G_MININT) x = c->frame->area.x - carea->x; - else if (o->x.opposite) x = area->width - w - x; - x += area->x; - - y = o->y.pos; - if (o->y.denom) - y = (y * area->height) / o->y.denom; - if (o->y.center) y = (area->height - h) / 2; - else if (y == G_MININT) y = c->frame->area.y - carea->y; - else if (o->y.opposite) y = area->height - h - y; - y += area->y; - - /* get the client's size back */ - w -= c->frame->size.left + c->frame->size.right; - h -= c->frame->size.top + c->frame->size.bottom; - - frame_frame_gravity(c->frame, &x, &y); /* get the client coords */ - client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE); - /* force it on screen if its moving to another monitor */ - client_find_onscreen(c, &x, &y, w, h, mon != cmon); + area = screen_area(c->desktop, mon, NULL); + carea = screen_area(c->desktop, cmon, NULL); + + w = o->w; + if (w == G_MININT) w = c->area.width; + else if (o->w_denom) w = (w * area->width) / o->w_denom; + + h = o->h; + if (h == G_MININT) h = c->area.height; + else if (o->h_denom) h = (h * area->height) / o->h_denom; + + /* it might not be able to resize how they requested, so find out what + it will actually be resized to */ + x = c->area.x; + y = c->area.y; + client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE); + + /* get the frame's size */ + w += c->frame->size.left + c->frame->size.right; + h += c->frame->size.top + c->frame->size.bottom; + + x = o->x.pos; + if (o->x.denom) + x = (x * area->width) / o->x.denom; + if (o->x.center) x = (area->width - w) / 2; + else if (x == G_MININT) x = c->frame->area.x - carea->x; + else if (o->x.opposite) x = area->width - w - x; + x += area->x; + + y = o->y.pos; + if (o->y.denom) + y = (y * area->height) / o->y.denom; + if (o->y.center) y = (area->height - h) / 2; + else if (y == G_MININT) y = c->frame->area.y - carea->y; + else if (o->y.opposite) y = area->height - h - y; + y += area->y; + + /* get the client's size back */ + w -= c->frame->size.left + c->frame->size.right; + h -= c->frame->size.top + c->frame->size.bottom; + + frame_frame_gravity(c->frame, &x, &y); /* get the client coords */ + client_try_configure(c, &x, &y, &w, &h, &lw, &lh, TRUE); + /* force it on screen if its moving to another monitor */ + client_find_onscreen(c, &x, &y, w, h, mon != cmon); + + client_configure(c, x, y, w, h, TRUE, TRUE, FALSE); + + g_slice_free(Rect, area); + g_slice_free(Rect, carea); + return TRUE; +} +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_configure(c, x, y, w, h, TRUE, TRUE, FALSE); + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); - - g_slice_free(Rect, area); - g_slice_free(Rect, carea); } - return FALSE; } diff --git a/openbox/actions/movetoedge.c b/openbox/actions/movetoedge.c index c5f8062d..5ff1def7 100644 --- a/openbox/actions/movetoedge.c +++ b/openbox/actions/movetoedge.c @@ -3,6 +3,7 @@ #include "openbox/action_value.h" #include "openbox/misc.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/frame.h" #include "openbox/geom.h" #include @@ -13,7 +14,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_movetoedge_startup(void) { @@ -54,21 +56,26 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; + gint x, y; - if (data->target) { - gint x, y; + client_find_move_directional(c, o->dir, &x, &y); + if (x != c->area.x || y != c->area.y) + client_move(c, x, y); + return TRUE; +} - client_find_move_directional(data->target, o->dir, &x, &y); - if (x != data->target->area.x || y != data->target->area.y) { - action_client_move(data, TRUE); - client_move(data->target, x, y); - action_client_move(data, FALSE); - } +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_run, options); + action_client_move(data, FALSE); } - return FALSE; } diff --git a/openbox/actions/omnipresent.c b/openbox/actions/omnipresent.c index 7fc950c4..1bc304f6 100644 --- a/openbox/actions/omnipresent.c +++ b/openbox/actions/omnipresent.c @@ -1,24 +1,79 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/screen.h" -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options); +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_omnipresent_startup(void) { + action_register("Omnipresent", OB_ACTION_DEFAULT_FILTER_SINGLE, + NULL, NULL, run_func_on); + action_register("Unomnipresent", OB_ACTION_DEFAULT_FILTER_SINGLE, + NULL, NULL, run_func_off); action_register("ToggleOmnipresent", OB_ACTION_DEFAULT_FILTER_SINGLE, NULL, NULL, run_func_toggle); } +static gboolean each_off(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_set_desktop(c, FALSE, FALSE, TRUE); + return TRUE; +} + +/* Always return FALSE because its not interactive */ +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_off, options); + action_client_move(data, FALSE); + } + return FALSE; +} + +static gboolean each_on(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_set_desktop(c, TRUE, FALSE, TRUE); + return TRUE; +} + +/* Always return FALSE because its not interactive */ +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { + action_client_move(data, TRUE); + client_set_run(set, data, each_on, options); + action_client_move(data, FALSE); + } + return FALSE; +} + +static gboolean each_toggle(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + gboolean omni = c->desktop == DESKTOP_ALL ? screen_desktop : DESKTOP_ALL; + client_set_desktop(c, omni, FALSE, TRUE); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options) +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_set_desktop(data->target, - data->target->desktop == DESKTOP_ALL ? - screen_desktop : DESKTOP_ALL, FALSE, TRUE); + client_set_run(set, data, each_toggle, options); action_client_move(data, FALSE); } return FALSE; diff --git a/openbox/actions/raise.c b/openbox/actions/raise.c index 694a19c5..bac4492d 100644 --- a/openbox/actions/raise.c +++ b/openbox/actions/raise.c @@ -1,9 +1,11 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/stacking.h" #include "openbox/window.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_raise_startup(void) { @@ -11,12 +13,20 @@ void action_raise_startup(void) NULL, NULL, run_func); } +static gboolean each_run(struct _ObClient *c, const ObActionListRun *data, + gpointer options) +{ + stacking_raise(CLIENT_AS_WINDOW(c)); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - stacking_raise(CLIENT_AS_WINDOW(data->target)); + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); } diff --git a/openbox/actions/raiselower.c b/openbox/actions/raiselower.c index abb85de7..88eece6c 100644 --- a/openbox/actions/raiselower.c +++ b/openbox/actions/raiselower.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/stacking.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_raiselower_startup(void) { @@ -10,12 +12,20 @@ void action_raiselower_startup(void) NULL, NULL, run_func); } +static gboolean each_run(struct _ObClient *c, const ObActionListRun *data, + gpointer options) +{ + stacking_restack_request(c, NULL, Opposite); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target) { + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - stacking_restack_request(data->target, NULL, Opposite); + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); } diff --git a/openbox/actions/reconfigure.c b/openbox/actions/reconfigure.c index 13966c4d..11cf1a4b 100644 --- a/openbox/actions/reconfigure.c +++ b/openbox/actions/reconfigure.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/openbox.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_reconfigure_startup(void) { @@ -11,7 +13,8 @@ void action_reconfigure_startup(void) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { ob_reconfigure(); diff --git a/openbox/actions/resize.c b/openbox/actions/resize.c index 15572bf2..010aaba5 100644 --- a/openbox/actions/resize.c +++ b/openbox/actions/resize.c @@ -3,6 +3,7 @@ #include "openbox/action_value.h" #include "openbox/moveresize.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/frame.h" #include "obt/prop.h" @@ -13,7 +14,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer o); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); static guint32 pick_corner(gint x, gint y, gint cx, gint cy, gint cw, gint ch, gboolean shaded); @@ -64,34 +66,39 @@ static void free_func(gpointer o) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; + GList *list; + struct _ObClient *c; + guint32 corner; - if (data->target) { - ObClient *c = data->target; - guint32 corner; + /* only works on a single client */ + if (client_set_size(set) != 1) return FALSE; - if (!data->pointer_button) - corner = OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD); - else if (o->corner_specified) - corner = o->corner; /* it was specified in the binding */ - else - corner = pick_corner(data->pointer_x, data->pointer_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, c->shaded); - - moveresize_start(c, data->pointer_x, data->pointer_y, - data->pointer_button, corner); - } + list = client_set_get_all(set); + c = list->data; + g_list_free(list); + if (!data->pointer_button) + corner = OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD); + else if (o->corner_specified) + corner = o->corner; /* it was specified in the binding */ + else + corner = pick_corner(data->pointer_x, data->pointer_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, c->shaded); + + moveresize_start(c, data->pointer_x, data->pointer_y, + data->pointer_button, corner); return FALSE; } diff --git a/openbox/actions/resizerelative.c b/openbox/actions/resizerelative.c index 7cf986c2..933d0aa9 100644 --- a/openbox/actions/resizerelative.c +++ b/openbox/actions/resizerelative.c @@ -2,6 +2,7 @@ #include "openbox/action_list_run.h" #include "openbox/action_value.h" #include "openbox/client.h" +#include "openbox/client_set.h" #include "openbox/screen.h" #include "openbox/frame.h" #include "openbox/config.h" @@ -19,7 +20,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer options); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_resizerelative_startup(void) { @@ -55,46 +57,51 @@ static void free_func(gpointer o) g_slice_free(Options, o); } -/* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean each_run(ObClient *c, const ObActionListRun *data, + gpointer options) { Options *o = options; + gint x, y, ow, xoff, nw, oh, yoff, nh, lw, lh; + gint left = o->left, right = o->right, top = o->top, bottom = o->bottom; + + if (o->left_denom) + left = (left * c->area.width / c->size_inc.width) / o->left_denom; + if (o->right_denom) + right = (right * c->area.width / c->size_inc.width) / o->right_denom; + if (o->top_denom) + top = (top * c->area.height / c->size_inc.height) / o->top_denom; + if (o->bottom_denom) + bottom = (bottom * c->area.height / c->size_inc.height) / + o->bottom_denom; - if (data->target) { - ObClient *c = data->target; - gint x, y, ow, xoff, nw, oh, yoff, nh, lw, lh; - gint left = o->left, right = o->right, top = o->top, bottom = o->bottom; + x = c->area.x; + y = c->area.y; + ow = c->area.width; + xoff = -left * c->size_inc.width; + nw = ow + right * c->size_inc.width + left * c->size_inc.width; + oh = c->area.height; + yoff = -top * c->size_inc.height; + nh = oh + bottom * c->size_inc.height + top * c->size_inc.height; - if (o->left_denom) - left = (left * c->area.width / c->size_inc.width) / o->left_denom; - if (o->right_denom) - right = (right * c->area.width / c->size_inc.width) / o->right_denom; - if (o->top_denom) - top = (top * c->area.height / c->size_inc.height) / o->top_denom; - if (o->bottom_denom) - bottom = (bottom * c->area.height / c->size_inc.height) / o->bottom_denom; + client_try_configure(c, &x, &y, &nw, &nh, &lw, &lh, TRUE); + xoff = xoff == 0 ? 0 : + (xoff < 0 ? MAX(xoff, ow-nw) : MIN(xoff, ow-nw)); + yoff = yoff == 0 ? 0 : + (yoff < 0 ? MAX(yoff, oh-nh) : MIN(yoff, oh-nh)); - x = c->area.x; - y = c->area.y; - ow = c->area.width; - xoff = -left * c->size_inc.width; - nw = ow + right * c->size_inc.width - + left * c->size_inc.width; - oh = c->area.height; - yoff = -top * c->size_inc.height; - nh = oh + bottom * c->size_inc.height - + top * c->size_inc.height; + client_move_resize(c, x + xoff, y + yoff, nw, nh); - client_try_configure(c, &x, &y, &nw, &nh, &lw, &lh, TRUE); - xoff = xoff == 0 ? 0 : - (xoff < 0 ? MAX(xoff, ow-nw) : MIN(xoff, ow-nw)); - yoff = yoff == 0 ? 0 : - (yoff < 0 ? MAX(yoff, oh-nh) : MIN(yoff, oh-nh)); + return TRUE; +} +/* Always return FALSE because its not interactive */ +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) +{ + if (!client_set_is_empty(set)) { action_client_move(data, TRUE); - client_move_resize(c, x + xoff, y + yoff, nw, nh); + client_set_run(set, data, each_run, options); action_client_move(data, FALSE); } - return FALSE; } diff --git a/openbox/actions/restart.c b/openbox/actions/restart.c index 9521e814..3b5750f0 100644 --- a/openbox/actions/restart.c +++ b/openbox/actions/restart.c @@ -1,6 +1,7 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/action_value.h" +#include "openbox/client_set.h" #include "openbox/openbox.h" #include "obt/paths.h" @@ -10,7 +11,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer options); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_restart_startup(void) { @@ -39,7 +41,8 @@ static void free_func(gpointer options) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; diff --git a/openbox/actions/shade.c b/openbox/actions/shade.c index f97c5171..489891a5 100644 --- a/openbox/actions/shade.c +++ b/openbox/actions/shade.c @@ -1,10 +1,14 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/client.h" +#include "openbox/client_set.h" -static gboolean run_func_on(const ObActionListRun *data, gpointer options); -static gboolean run_func_off(const ObActionListRun *data, gpointer options); -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options); +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options); +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_shade_startup(void) { @@ -16,34 +20,58 @@ void action_shade_startup(void) NULL, NULL, run_func_toggle); } +static gboolean each_on(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_shade(c, TRUE); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_on(const ObActionListRun *data, gpointer options) +static gboolean run_func_on(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { if (data->target) { action_client_move(data, TRUE); - client_shade(data->target, TRUE); + client_set_run(set, data, each_on, options); action_client_move(data, FALSE); } return FALSE; } +static gboolean each_off(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_shade(c, FALSE); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_off(const ObActionListRun *data, gpointer options) +static gboolean run_func_off(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { if (data->target) { action_client_move(data, TRUE); - client_shade(data->target, FALSE); + client_set_run(set, data, each_off, options); action_client_move(data, FALSE); } return FALSE; } +static gboolean each_toggle(ObClient *c, const ObActionListRun *data, + gpointer options) +{ + client_shade(c, !c->shaded); + return TRUE; +} + /* Always return FALSE because its not interactive */ -static gboolean run_func_toggle(const ObActionListRun *data, gpointer options) +static gboolean run_func_toggle(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { if (data->target) { action_client_move(data, TRUE); - client_shade(data->target, !data->target->shaded); + client_set_run(set, data, each_toggle, options); action_client_move(data, FALSE); } return FALSE; diff --git a/openbox/actions/showdesktop.c b/openbox/actions/showdesktop.c index 3b31a955..62af374a 100644 --- a/openbox/actions/showdesktop.c +++ b/openbox/actions/showdesktop.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/screen.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_showdesktop_startup(void) { @@ -11,7 +13,8 @@ void action_showdesktop_startup(void) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { screen_show_desktop(!screen_showing_desktop, NULL); diff --git a/openbox/actions/showmenu.c b/openbox/actions/showmenu.c index 272c7de5..256751ef 100644 --- a/openbox/actions/showmenu.c +++ b/openbox/actions/showmenu.c @@ -1,6 +1,7 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" #include "openbox/action_value.h" +#include "openbox/client_set.h" #include "openbox/menu.h" #include @@ -10,7 +11,8 @@ typedef struct { static gpointer setup_func(GHashTable *config); static void free_func(gpointer options); -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_showmenu_startup(void) { @@ -39,14 +41,25 @@ static void free_func(gpointer options) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { Options *o = options; + GList *list; + struct _ObClient *c; + + /* this can't work on more than one window */ + if (client_set_size(set) > 1) return FALSE; + + list = client_set_get_all(set); + if (list) c = list->data; + else c = NULL; + g_list_free(list); /* you cannot call ShowMenu from inside a menu */ if (data->user_act != OB_USER_ACTION_MENU_SELECTION && o->name) menu_show(o->name, data->pointer_x, data->pointer_y, - data->pointer_button != 0, data->target); + data->pointer_button != 0, c); return FALSE; } diff --git a/openbox/actions/unfocus.c b/openbox/actions/unfocus.c index 40d7b282..7ec991b6 100644 --- a/openbox/actions/unfocus.c +++ b/openbox/actions/unfocus.c @@ -1,8 +1,10 @@ #include "openbox/action.h" #include "openbox/action_list_run.h" +#include "openbox/client_set.h" #include "openbox/focus.h" -static gboolean run_func(const ObActionListRun *data, gpointer options); +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options); void action_unfocus_startup(void) { @@ -11,9 +13,10 @@ void action_unfocus_startup(void) } /* Always return FALSE because its not interactive */ -static gboolean run_func(const ObActionListRun *data, gpointer options) +static gboolean run_func(const ObClientSet *set, + const ObActionListRun *data, gpointer options) { - if (data->target && data->target == focus_client) + if (focus_client && client_set_contains(set, focus_client)) focus_fallback(FALSE, FALSE, TRUE, FALSE); return FALSE; } diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c index 6d4cc2a5..5510c371 100644 --- a/openbox/focus_cycle.c +++ b/openbox/focus_cycle.c @@ -20,6 +20,7 @@ #include "focus_cycle.h" #include "focus_cycle_indicator.h" #include "client.h" +#include "client_set.h" #include "frame.h" #include "focus.h" #include "screen.h" @@ -36,16 +37,16 @@ typedef enum { } ObCycleType; ObClient *focus_cycle_target = NULL; +ObClientSet *focus_cycle_set = NULL; static ObCycleType focus_cycle_type = OB_CYCLE_NONE; static gboolean focus_cycle_linear; static gboolean focus_cycle_iconic_windows; -static gboolean focus_cycle_all_desktops; -static gboolean focus_cycle_nonhilite_windows; static gboolean focus_cycle_dock_windows; static gboolean focus_cycle_desktop_windows; static ObClient *focus_find_directional(ObClient *c, ObDirection dir, + const ObClientSet *set, gboolean dock_windows, gboolean desktop_windows); @@ -66,7 +67,8 @@ void focus_cycle_addremove(ObClient *c, gboolean redraw) if (focus_cycle_type == OB_CYCLE_DIRECTIONAL) { if (c && focus_cycle_target == c) { - focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, + /* cancel it */ + focus_directional_cycle(0, NULL, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); } } @@ -87,19 +89,19 @@ void focus_cycle_addremove(ObClient *c, gboolean redraw) void focus_cycle_reorder() { if (focus_cycle_type == OB_CYCLE_NORMAL) { - focus_cycle_target = focus_cycle_popup_refresh(focus_cycle_target, + focus_cycle_target = focus_cycle_popup_refresh(focus_cycle_set, + focus_cycle_target, TRUE, focus_cycle_linear); focus_cycle_update_indicator(focus_cycle_target); if (!focus_cycle_target) - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, + focus_cycle(NULL, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, OB_FOCUS_CYCLE_POPUP_MODE_NONE, TRUE, TRUE); } } -ObClient* focus_cycle(gboolean forward, gboolean all_desktops, - gboolean nonhilite_windows, +ObClient* focus_cycle(const ObClientSet *set, gboolean forward, gboolean dock_windows, gboolean desktop_windows, gboolean linear, gboolean interactive, gboolean showbar, ObFocusCyclePopupMode mode, @@ -129,10 +131,9 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, } if (focus_cycle_target == NULL) { + focus_cycle_set = client_set_clone(set); focus_cycle_linear = linear; focus_cycle_iconic_windows = TRUE; - focus_cycle_all_desktops = all_desktops; - focus_cycle_nonhilite_windows = nonhilite_windows; focus_cycle_dock_windows = dock_windows; focus_cycle_desktop_windows = desktop_windows; start = it = g_list_find(list, focus_client); @@ -160,7 +161,8 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops, focus_cycle_draw_indicator(showbar ? ft : NULL); } /* same arguments as focus_target_valid */ - focus_cycle_popup_show(ft, mode, focus_cycle_linear); + focus_cycle_popup_show(focus_cycle_set, ft, mode, + focus_cycle_linear); return focus_cycle_target; } else if (ft != focus_cycle_target) { focus_cycle_target = ft; @@ -175,6 +177,8 @@ done_cycle: if (done && !cancel) ret = focus_cycle_target; focus_cycle_target = NULL; + client_set_destroy(focus_cycle_set); + focus_cycle_set = NULL; focus_cycle_type = OB_CYCLE_NONE; g_list_free(order); order = NULL; @@ -189,6 +193,7 @@ done_cycle: /* this be mostly ripped from fvwm */ static ObClient *focus_find_directional(ObClient *c, ObDirection dir, + const ObClientSet *set, gboolean dock_windows, gboolean desktop_windows) { @@ -282,7 +287,8 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir, return best_client; } -ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, +ObClient* focus_directional_cycle(ObDirection dir, const ObClientSet *set, + gboolean dock_windows, gboolean desktop_windows, gboolean interactive, gboolean showbar, gboolean dialog, @@ -302,10 +308,9 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, goto done_cycle; if (focus_cycle_target == NULL) { + focus_cycle_set = client_set_clone(set); focus_cycle_linear = FALSE; focus_cycle_iconic_windows = FALSE; - focus_cycle_all_desktops = FALSE; - focus_cycle_nonhilite_windows = TRUE; focus_cycle_dock_windows = dock_windows; focus_cycle_desktop_windows = desktop_windows; } @@ -313,10 +318,11 @@ ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows, if (!first) first = focus_client; if (focus_cycle_target) - ft = focus_find_directional(focus_cycle_target, dir, dock_windows, + ft = focus_find_directional(focus_cycle_target, dir, set, dock_windows, desktop_windows); else if (first) - ft = focus_find_directional(first, dir, dock_windows, desktop_windows); + ft = focus_find_directional(first, dir, set, dock_windows, + desktop_windows); else { GList *it; @@ -344,6 +350,8 @@ done_cycle: first = NULL; focus_cycle_target = NULL; + client_set_destroy(focus_cycle_set); + focus_cycle_set = NULL; focus_cycle_type = OB_CYCLE_NONE; focus_cycle_draw_indicator(NULL); @@ -354,11 +362,13 @@ done_cycle: gboolean focus_cycle_valid(struct _ObClient *client) { - return focus_valid_target(client, screen_desktop, TRUE, - focus_cycle_iconic_windows, - focus_cycle_all_desktops, - focus_cycle_nonhilite_windows, - focus_cycle_dock_windows, - focus_cycle_desktop_windows, - FALSE); + return + client_set_contains(focus_cycle_set, client) && + focus_valid_target(client, screen_desktop, TRUE, + focus_cycle_iconic_windows, + TRUE, /* all desktops */ + TRUE, /* non-hilite windows */ + focus_cycle_dock_windows, + focus_cycle_desktop_windows, + FALSE); } diff --git a/openbox/focus_cycle.h b/openbox/focus_cycle.h index 9394b3df..7e32db9d 100644 --- a/openbox/focus_cycle.h +++ b/openbox/focus_cycle.h @@ -35,13 +35,15 @@ void focus_cycle_startup(gboolean reconfig); void focus_cycle_shutdown(gboolean reconfig); /*! Cycle focus amongst windows. */ -struct _ObClient* focus_cycle(gboolean forward, gboolean all_desktops, - gboolean nonhilite_windows, +struct _ObClient* focus_cycle(const struct _ObClientSet *set, + gboolean forward, gboolean dock_windows, gboolean desktop_windows, gboolean linear, gboolean interactive, gboolean showbar, ObFocusCyclePopupMode mode, gboolean done, gboolean cancel); + struct _ObClient* focus_directional_cycle(ObDirection dir, + const struct _ObClientSet *set, gboolean dock_windows, gboolean desktop_windows, gboolean interactive, diff --git a/openbox/focus_cycle_popup.c b/openbox/focus_cycle_popup.c index e1ea8488..6942d4ef 100644 --- a/openbox/focus_cycle_popup.c +++ b/openbox/focus_cycle_popup.c @@ -21,6 +21,7 @@ #include "focus_cycle.h" #include "popup.h" #include "client.h" +#include "client_set.h" #include "screen.h" #include "focus.h" #include "openbox.h" @@ -101,6 +102,7 @@ static ObIconPopup *single_popup; static gchar *popup_get_name (ObClient *c); static gboolean popup_setup (ObFocusCyclePopup *p, + const ObClientSet *set, gboolean create_targets, gboolean refresh_targets, gboolean linear); @@ -250,8 +252,9 @@ static void popup_target_free(ObFocusCyclePopupTarget *t) g_slice_free(ObFocusCyclePopupTarget, t); } -static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets, - gboolean refresh_targets, gboolean linear) +static gboolean popup_setup(ObFocusCyclePopup *p, const ObClientSet *set, + gboolean create_targets, gboolean refresh_targets, + gboolean linear) { gint maxwidth, n; GList *it; @@ -286,7 +289,7 @@ static gboolean popup_setup(ObFocusCyclePopup *p, gboolean create_targets, { ObClient *ft = it->data; - if (focus_cycle_valid(ft)) { + if (client_set_contains(set, ft) && focus_cycle_valid(ft)) { GList *rit; /* reuse the target if possible during refresh */ @@ -704,8 +707,8 @@ static void popup_render(ObFocusCyclePopup *p, const ObClient *c) XFlush(obt_display); } -void focus_cycle_popup_show(ObClient *c, ObFocusCyclePopupMode mode, - gboolean linear) +void focus_cycle_popup_show(const ObClientSet *set, ObClient *c, + ObFocusCyclePopupMode mode, gboolean linear) { g_assert(c != NULL); @@ -716,7 +719,7 @@ void focus_cycle_popup_show(ObClient *c, ObFocusCyclePopupMode mode, /* do this stuff only when the dialog is first showing */ if (!popup.mapped) { - popup_setup(&popup, TRUE, FALSE, linear); + popup_setup(&popup, set, TRUE, FALSE, linear); /* this is fixed once the dialog is shown */ popup.mode = mode; } @@ -822,7 +825,8 @@ static ObClient* popup_revert(ObClient *target) return NULL; } -ObClient* focus_cycle_popup_refresh(ObClient *target, +ObClient* focus_cycle_popup_refresh(const ObClientSet *set, + ObClient *target, gboolean redraw, gboolean linear) { @@ -831,7 +835,7 @@ ObClient* focus_cycle_popup_refresh(ObClient *target, if (!focus_cycle_valid(target)) target = popup_revert(target); - redraw = popup_setup(&popup, TRUE, TRUE, linear) && redraw; + redraw = popup_setup(&popup, set, TRUE, TRUE, linear) && redraw; if (!target && popup.targets) target = ((ObFocusCyclePopupTarget*)popup.targets->data)->client; diff --git a/openbox/focus_cycle_popup.h b/openbox/focus_cycle_popup.h index 8c80bfcf..b5bc6777 100644 --- a/openbox/focus_cycle_popup.h +++ b/openbox/focus_cycle_popup.h @@ -21,6 +21,7 @@ #define __focus_cycle_popup_h struct _ObClient; +struct _ObClientSet; #include @@ -33,8 +34,9 @@ typedef enum { void focus_cycle_popup_startup(gboolean reconfig); void focus_cycle_popup_shutdown(gboolean reconfig); -void focus_cycle_popup_show(struct _ObClient *c, ObFocusCyclePopupMode mode, - gboolean linear); +void focus_cycle_popup_show(const struct _ObClientSet *set, + struct _ObClient *c, + ObFocusCyclePopupMode mode, gboolean linear); void focus_cycle_popup_hide(void); void focus_cycle_popup_single_show(struct _ObClient *c); @@ -46,7 +48,8 @@ gboolean focus_cycle_popup_is_showing(struct _ObClient *c); the target given to the function is no longer valid, this will return a different target that is valid, and which should be considered the current focus cycling target. */ -struct _ObClient *focus_cycle_popup_refresh(struct _ObClient *target, +struct _ObClient *focus_cycle_popup_refresh(const struct _ObClientSet *set, + struct _ObClient *target, gboolean redraw, gboolean linear);