summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
Diffstat (limited to 'openbox')
-rw-r--r--openbox/action.c29
-rw-r--r--openbox/actions/activate.c79
-rw-r--r--openbox/actions/all.c1
-rw-r--r--openbox/actions/all.h1
-rw-r--r--openbox/client.c28
-rw-r--r--openbox/client.h5
-rw-r--r--openbox/client_list_combined_menu.c2
-rw-r--r--openbox/client_list_menu.c2
-rw-r--r--openbox/event.c4
-rw-r--r--openbox/focus_cycle.c18
-rw-r--r--openbox/focus_cycle.h9
11 files changed, 118 insertions, 60 deletions
diff --git a/openbox/action.c b/openbox/action.c
index 7f0cca15..de2bcdcc 100644
--- a/openbox/action.c
+++ b/openbox/action.c
@@ -499,11 +499,6 @@ ActionString actionstrings[] =
setup_action_directional_focus_northwest
},
{
- "activate",
- action_activate,
- setup_action_focus
- },
- {
"focus",
action_focus,
setup_action_focus
@@ -965,9 +960,6 @@ ObAction *action_parse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.sendtodir.inter.any.interactive =
parse_bool(doc, n);
- } else if (act->func == action_activate) {
- if ((n = parse_find_node("here", node->xmlChildrenNode)))
- act->data.activate.here = parse_bool(doc, n);
} else if (act->func == action_directional_focus) {
if ((n = parse_find_node("dialog", node->xmlChildrenNode)))
act->data.interdiraction.dialog = parse_bool(doc, n);
@@ -1118,27 +1110,6 @@ void action_run_string(const gchar *name, struct _ObClient *c, Time time)
action_run(l, c, 0, time);
}
-void action_activate(union ActionData *data)
-{
- if (data->client.any.c) {
- if (!data->any.button || client_mouse_focusable(data->client.any.c) ||
- (data->any.context != OB_FRAME_CONTEXT_CLIENT &&
- data->any.context != OB_FRAME_CONTEXT_FRAME))
- {
- /* if using focus_delay, stop the timer now so that focus doesn't
- go moving on us */
- event_halt_focus_delay();
-
- client_activate(data->activate.any.c, data->activate.here, TRUE);
- }
- } else {
- /* focus action on something other than a client, make keybindings
- work for this openbox instance, but don't focus any specific client
- */
- focus_nothing();
- }
-}
-
void action_focus(union ActionData *data)
{
if (data->client.any.c) {
diff --git a/openbox/actions/activate.c b/openbox/actions/activate.c
new file mode 100644
index 00000000..66923622
--- /dev/null
+++ b/openbox/actions/activate.c
@@ -0,0 +1,79 @@
+#include "openbox/actions.h"
+#include "openbox/event.h"
+#include "openbox/client.h"
+#include "openbox/focus.h"
+
+typedef struct {
+ gboolean here;
+ gboolean raise;
+ gboolean unshade;
+} Options;
+
+static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
+static void free_func(gpointer options);
+static gboolean run_func(ObActionsData *data, gpointer options);
+
+void action_activate_startup()
+{
+ actions_register("Activate",
+ setup_func,
+ free_func,
+ run_func,
+ NULL, NULL);
+}
+
+static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
+{
+ xmlNodePtr n;
+ Options *o;
+
+ o = g_new0(Options, 1);
+ o->raise = TRUE;
+ o->unshade = TRUE;
+
+ if ((n = parse_find_node("here", node)))
+ o->here = parse_bool(doc, n);
+ if ((n = parse_find_node("raise", node)))
+ o->raise = parse_bool(doc, n);
+ if ((n = parse_find_node("unshade", node)))
+ o->unshade = parse_bool(doc, n);
+ return o;
+}
+
+static void free_func(gpointer options)
+{
+ Options *o = options;
+
+ g_free(o);
+}
+
+/* Always return FALSE because its not interactive */
+static gboolean run_func(ObActionsData *data, gpointer options)
+{
+ Options *o = options;
+
+ if (data->client) {
+ gboolean mouse = (data->uact == OB_USER_ACTION_MOUSE_PRESS ||
+ data->uact == OB_USER_ACTION_MOUSE_RELEASE ||
+ data->uact == OB_USER_ACTION_MOUSE_CLICK ||
+ data->uact == OB_USER_ACTION_MOUSE_DOUBLE_CLICK ||
+ data->uact == OB_USER_ACTION_MOUSE_MOTION);
+ if (!mouse || client_mouse_focusable(data->client) ||
+ data->context != OB_FRAME_CONTEXT_CLIENT ||
+ data->context != OB_FRAME_CONTEXT_FRAME)
+ {
+ /* if using focus_delay, stop the timer now so that focus doesn't
+ go moving on us */
+ event_halt_focus_delay();
+
+ client_activate(data->client, o->here, o->raise, o->unshade, TRUE);
+ }
+ } else {
+ /* focus action on something other than a client, make keybindings
+ work for this openbox instance, but don't focus any specific client
+ */
+ focus_nothing();
+ }
+
+ return FALSE;
+}
diff --git a/openbox/actions/all.c b/openbox/actions/all.c
index d60693b4..a8cf305f 100644
--- a/openbox/actions/all.c
+++ b/openbox/actions/all.c
@@ -10,4 +10,5 @@ void action_all_startup()
action_exit_startup();
action_restart_startup();
action_cyclewindows_startup();
+ action_activate_startup();
}
diff --git a/openbox/actions/all.h b/openbox/actions/all.h
index c3ab3a87..1f9a7f38 100644
--- a/openbox/actions/all.h
+++ b/openbox/actions/all.h
@@ -11,5 +11,6 @@ void action_reconfigure_startup();
void action_exit_startup();
void action_restart_startup();
void action_cyclewindows_startup();
+void action_activate_startup();
#endif
diff --git a/openbox/client.c b/openbox/client.c
index 771294a4..d65ce4a1 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -88,7 +88,8 @@ static void client_update_transient_tree(ObClient *self,
gboolean oldgtran, gboolean newgtran,
ObClient* oldparent,
ObClient *newparent);
-static void client_present(ObClient *self, gboolean here, gboolean raise);
+static void client_present(ObClient *self, gboolean here, gboolean raise,
+ gboolean unshade);
static GSList *client_search_all_top_parents_internal(ObClient *self,
gboolean bylayer,
ObStackingLayer layer);
@@ -544,7 +545,7 @@ void client_manage(Window window)
if (activate) {
gboolean stacked = client_restore_session_stacking(self);
- client_present(self, FALSE, !stacked);
+ client_present(self, FALSE, !stacked, TRUE);
}
/* add to client list/map */
@@ -3561,6 +3562,10 @@ gboolean client_focus(ObClient *self)
"Focusing client \"%s\" (0x%x) at time %u\n",
self->title, self->window, event_curtime);
+ /* if using focus_delay, stop the timer now so that focus doesn't
+ go moving on us */
+ event_halt_focus_delay();
+
/* if there is a grab going on, then we need to cancel it. if we move
focus during the grab, applications will get NotifyWhileGrabbed events
and ignore them !
@@ -3601,17 +3606,9 @@ gboolean client_focus(ObClient *self)
return !xerror_occured;
}
-/*! Present the client to the user.
- @param raise If the client should be raised or not. You should only set
- raise to false if you don't care if the window is completely
- hidden.
-*/
-static void client_present(ObClient *self, gboolean here, gboolean raise)
+static void client_present(ObClient *self, gboolean here, gboolean raise,
+ gboolean unshade)
{
- /* if using focus_delay, stop the timer now so that focus doesn't
- go moving on us */
- event_halt_focus_delay();
-
if (client_normal(self) && screen_showing_desktop)
screen_show_desktop(FALSE, self);
if (self->iconic)
@@ -3627,7 +3624,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
/* if its not visible for other reasons, then don't mess
with it */
return;
- if (self->shaded)
+ if (self->shaded && unshade)
client_shade(self, FALSE);
if (raise)
stacking_raise(CLIENT_AS_WINDOW(self));
@@ -3635,7 +3632,8 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
client_focus(self);
}
-void client_activate(ObClient *self, gboolean here, gboolean user)
+void client_activate(ObClient *self, gboolean here, gboolean raise,
+ gboolean unshade, gboolean user)
{
guint32 last_time = focus_client ? focus_client->user_time : CurrentTime;
gboolean allow = FALSE;
@@ -3661,7 +3659,7 @@ void client_activate(ObClient *self, gboolean here, gboolean user)
(user ? "user" : "application"), allow);
if (allow)
- client_present(self, here, TRUE);
+ client_present(self, here, raise, unshade);
else
/* don't focus it but tell the user it wants attention */
client_hilite(self, TRUE);
diff --git a/openbox/client.h b/openbox/client.h
index b30db198..bb783458 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -550,10 +550,13 @@ gboolean client_focus(ObClient *self);
when the user deliberately selects a window for use.
@param here If true, then the client is brought to the current desktop;
otherwise, the desktop is changed to where the client lives.
+ @param raise If true, the client is brought to the front.
+ @param unshade If true, the client is unshaded (if it is shaded)
@param user If true, then a user action is what requested the activation;
otherwise, it means an application requested it on its own
*/
-void client_activate(ObClient *self, gboolean here, gboolean user);
+void client_activate(ObClient *self, gboolean here, gboolean raise,
+ gboolean unshade, gboolean user);
/*! Bring all of its helper windows to its desktop. These are the utility and
stuff windows. */
diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c
index 60d6e687..998fd0a3 100644
--- a/openbox/client_list_combined_menu.c
+++ b/openbox/client_list_combined_menu.c
@@ -98,7 +98,7 @@ static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
{
if (self->id == -1) {
if (self->data.normal.data) /* it's set to NULL if its destroyed */
- client_activate(self->data.normal.data, FALSE, TRUE);
+ client_activate(self->data.normal.data, FALSE, TRUE, TRUE, TRUE);
}
else
screen_set_desktop(self->id, TRUE);
diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c
index 512cb3e8..8f8beed5 100644
--- a/openbox/client_list_menu.c
+++ b/openbox/client_list_menu.c
@@ -98,7 +98,7 @@ static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f,
{
if (self->id == -1) {
if (self->data.normal.data) /* it's set to NULL if its destroyed */
- client_activate(self->data.normal.data, FALSE, TRUE);
+ client_activate(self->data.normal.data, FALSE, TRUE, TRUE, TRUE);
}
else
screen_set_desktop(self->id, TRUE);
diff --git a/openbox/event.c b/openbox/event.c
index cd66014b..ab4e8f9a 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -1219,7 +1219,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
it can happen now when the window is on
another desktop, but we still don't
want it! */
- client_activate(client, FALSE, TRUE);
+ client_activate(client, FALSE, TRUE, TRUE, TRUE);
break;
case ClientMessage:
/* validate cuz we query stuff off the client here */
@@ -1297,7 +1297,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
ob_debug_type(OB_DEBUG_APP_BUGS,
"_NET_ACTIVE_WINDOW message for window %s is "
"missing source indication\n");
- client_activate(client, FALSE,
+ client_activate(client, FALSE, TRUE, TRUE,
(e->xclient.data.l[0] == 0 ||
e->xclient.data.l[0] == 2));
} else if (msgtype == prop_atoms.net_wm_moveresize) {
diff --git a/openbox/focus_cycle.c b/openbox/focus_cycle.c
index 971f116f..22398851 100644
--- a/openbox/focus_cycle.c
+++ b/openbox/focus_cycle.c
@@ -137,7 +137,7 @@ ObClient* focus_cycle(gboolean forward, gboolean all_desktops,
focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows);
- return;
+ return NULL;
} else if (ft != focus_cycle_target) {
focus_cycle_target = ft;
done = TRUE;
@@ -258,12 +258,15 @@ static ObClient *focus_find_directional(ObClient *c, ObDirection dir,
return best_client;
}
-void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
- gboolean desktop_windows, gboolean interactive,
- gboolean dialog, gboolean done, gboolean cancel)
+ObClient* focus_directional_cycle(ObDirection dir, gboolean dock_windows,
+ gboolean desktop_windows,
+ gboolean interactive,
+ gboolean dialog,
+ gboolean done, gboolean cancel)
{
static ObClient *first = NULL;
ObClient *ft = NULL;
+ ObClient *ret = NULL;
if (cancel) {
focus_cycle_target = NULL;
@@ -313,11 +316,10 @@ void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows);
- return;
+ return NULL;
done_cycle:
- if (done && focus_cycle_target)
- client_activate(focus_cycle_target, FALSE, TRUE);
+ if (done && !cancel) ret = focus_cycle_target;
first = NULL;
focus_cycle_target = NULL;
@@ -325,5 +327,5 @@ done_cycle:
focus_cycle_draw_indicator(NULL);
focus_cycle_popup_single_hide();
- return;
+ return ret;
}
diff --git a/openbox/focus_cycle.h b/openbox/focus_cycle.h
index 3fecc9e4..68b8d929 100644
--- a/openbox/focus_cycle.h
+++ b/openbox/focus_cycle.h
@@ -38,9 +38,12 @@ struct _ObClient* focus_cycle(gboolean forward, gboolean all_desktops,
gboolean dock_windows, gboolean desktop_windows,
gboolean linear, gboolean interactive,
gboolean dialog, gboolean done, gboolean cancel);
-void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
- gboolean desktop_windows, gboolean interactive,
- gboolean dialog, gboolean done, gboolean cancel);
+struct _ObClient* focus_directional_cycle(ObDirection dir,
+ gboolean dock_windows,
+ gboolean desktop_windows,
+ gboolean interactive,
+ gboolean dialog,
+ gboolean done, gboolean cancel);
void focus_cycle_stop(struct _ObClient *ifclient);