summaryrefslogtreecommitdiff
path: root/openbox
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2009-12-08 14:19:04 -0500
committerDana Jansens <danakj@orodu.net>2009-12-08 14:19:04 -0500
commit2f09e0ce388f63c341cb328d795766e2bd0dc24b (patch)
tree14fb36919947e80ba0dfc151d0f1f02ed46fd712 /openbox
parent84843c3f9842046e34366202f1a8f80ce8565f91 (diff)
parent672aea85cfe2ac2bc8cb4e3f34fd023f10d90182 (diff)
Merge branch 'backport' into work
Conflicts: openbox/actions/all.h openbox/actions/session.c openbox/client.c openbox/event.c openbox/grab.c
Diffstat (limited to 'openbox')
-rw-r--r--openbox/actions/all.c1
-rw-r--r--openbox/actions/all.h1
-rw-r--r--openbox/actions/exit.c26
-rw-r--r--openbox/client.c250
-rw-r--r--openbox/client.h6
-rw-r--r--openbox/client_list_combined_menu.c2
-rw-r--r--openbox/client_list_menu.c2
-rw-r--r--openbox/event.c7
-rw-r--r--openbox/focus.c6
-rw-r--r--openbox/session.c6
-rw-r--r--openbox/session.h2
11 files changed, 162 insertions, 147 deletions
diff --git a/openbox/actions/all.c b/openbox/actions/all.c
index 952d756d..4563e65f 100644
--- a/openbox/actions/all.c
+++ b/openbox/actions/all.c
@@ -9,7 +9,6 @@ void action_all_startup(void)
action_reconfigure_startup();
action_exit_startup();
action_restart_startup();
- action_session_startup();
action_cyclewindows_startup();
action_breakchroot_startup();
action_close_startup();
diff --git a/openbox/actions/all.h b/openbox/actions/all.h
index 1f520b93..6acbc9ca 100644
--- a/openbox/actions/all.h
+++ b/openbox/actions/all.h
@@ -10,7 +10,6 @@ void action_showdesktop_startup(void);
void action_reconfigure_startup(void);
void action_exit_startup(void);
void action_restart_startup(void);
-void action_session_startup(void);
void action_cyclewindows_startup(void);
void action_breakchroot_startup(void);
void action_close_startup(void);
diff --git a/openbox/actions/exit.c b/openbox/actions/exit.c
index 4f8cce6e..3bfebbce 100644
--- a/openbox/actions/exit.c
+++ b/openbox/actions/exit.c
@@ -1,6 +1,7 @@
#include "openbox/actions.h"
#include "openbox/openbox.h"
#include "openbox/prompt.h"
+#include "openbox/session.h"
#include "gettext.h"
typedef struct {
@@ -13,6 +14,7 @@ static gboolean run_func(ObActionsData *data, gpointer options);
void action_exit_startup(void)
{
actions_register("Exit", setup_func, NULL, run_func, NULL, NULL);
+ actions_register("SessionLogout", setup_func, NULL, run_func, NULL, NULL);
}
static gpointer setup_func(xmlNodePtr node)
@@ -29,10 +31,18 @@ static gpointer setup_func(xmlNodePtr node)
return o;
}
+static void do_exit(void)
+{
+ if (session_connected())
+ session_request_logout(FALSE);
+ else
+ ob_exit(0);
+}
+
static gboolean prompt_cb(ObPrompt *p, gint result, gpointer data)
{
if (result)
- ob_exit(0);
+ do_exit();
return TRUE; /* call the cleanup func */
}
@@ -53,13 +63,19 @@ static gboolean run_func(ObActionsData *data, gpointer options)
{ _("Exit"), 1 }
};
- p = prompt_new(_("Are you sure you want to exit Openbox?"),
- _("Exit Openbox"),
- answers, 2, 0, 0, prompt_cb, prompt_cleanup, NULL);
+ if (session_connected())
+ p = prompt_new(_("Are you sure you want to log out?"),
+ _("Log Out"),
+ answers, 2, 0, 0, prompt_cb, prompt_cleanup, NULL);
+ else
+ p = prompt_new(_("Are you sure you want to exit Openbox?"),
+ _("Exit Openbox"),
+ answers, 2, 0, 0, prompt_cb, prompt_cleanup, NULL);
+
prompt_show(p, NULL, FALSE);
}
else
- ob_exit(0);
+ do_exit();
return FALSE;
}
diff --git a/openbox/client.c b/openbox/client.c
index fc087d44..50a0dbee 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -105,6 +105,8 @@ static GSList *client_search_all_top_parents_internal(ObClient *self,
static void client_call_notifies(ObClient *self, GSList *list);
static void client_ping_event(ObClient *self, gboolean dead);
static void client_prompt_kill(ObClient *self);
+static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
+ Time launch_time);
void client_startup(gboolean reconfig)
{
@@ -418,121 +420,14 @@ void client_manage(Window window, ObPrompt *prompt)
ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s",
activate ? "yes" : "no");
if (activate) {
- gboolean raise = FALSE;
- gboolean relative_focused;
- gboolean parent_focused;
-
- parent_focused = (focus_client != NULL &&
- client_search_focus_parent(self));
- relative_focused = (focus_client != NULL &&
- (client_search_focus_tree_full(self) != NULL ||
- client_search_focus_group_full(self) != NULL));
-
- /* This is focus stealing prevention */
- ob_debug_type(OB_DEBUG_FOCUS,
- "Want to focus new window 0x%x at time %u "
- "launched at %u (last user interaction time %u)",
- self->window, map_time, launch_time,
- event_last_user_time);
- ob_debug_type(OB_DEBUG_FOCUS,
- "Current focus_client: %s",
- (focus_client ? focus_client->title : "(none)"));
- ob_debug_type(OB_DEBUG_FOCUS,
- "parent focused: %d relative focused: %d",
- parent_focused, relative_focused);
-
- if (menu_frame_visible || moveresize_in_progress) {
- activate = FALSE;
- raise = TRUE;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Not focusing the window because the user is inside "
- "an Openbox menu or is move/resizing a window and "
- "we don't want to interrupt them");
- }
-
- /* if it's on another desktop */
- else if (!(self->desktop == screen_desktop ||
- self->desktop == DESKTOP_ALL) &&
- /* the timestamp is from before you changed desktops */
- launch_time && screen_desktop_user_time &&
- !event_time_after(launch_time, screen_desktop_user_time))
- {
- activate = FALSE;
- raise = TRUE;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Not focusing the window because its on another "
- "desktop");
- }
- /* If something is focused... */
- else if (focus_client) {
- /* If the user is working in another window right now, then don't
- steal focus */
- if (!parent_focused &&
- event_last_user_time && launch_time &&
- event_time_after(event_last_user_time, launch_time) &&
- event_last_user_time != launch_time &&
- event_time_after(event_last_user_time,
- map_time - OB_EVENT_USER_TIME_DELAY))
- {
- activate = FALSE;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Not focusing the window because the user is "
- "working in another window that is not "
- "its parent");
- }
- /* If the new window is a transient (and its relatives aren't
- focused) */
- else if (client_has_parent(self) && !relative_focused) {
- activate = FALSE;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Not focusing the window because it is a "
- "transient, and its relatives aren't focused");
- }
- /* Don't steal focus from globally active clients.
- I stole this idea from KWin. It seems nice.
- */
- else if (!(focus_client->can_focus ||
- focus_client->focus_notify))
- {
- activate = FALSE;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Not focusing the window because a globally "
- "active client has focus");
- }
- /* Don't move focus if it's not going to go to this window
- anyway */
- else if (client_focus_target(self) != self) {
- activate = FALSE;
- raise = TRUE;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Not focusing the window because another window "
- "would get the focus anyway");
- }
- /* Don't move focus if the window is not visible on the current
- desktop and none of its relatives are focused */
- else if (!(self->desktop == screen_desktop ||
- self->desktop == DESKTOP_ALL) &&
- !relative_focused)
- {
- activate = FALSE;
- raise = TRUE;
- ob_debug_type(OB_DEBUG_FOCUS,
- "Not focusing the window because it is on "
- "another desktop and no relatives are focused ");
- }
- }
+ activate = client_can_steal_focus(self, map_time, launch_time);
if (!activate) {
- ob_debug_type(OB_DEBUG_FOCUS,
- "Focus stealing prevention activated for %s at "
- "time %u (last user interaction time %u)",
- self->title, map_time, event_last_user_time);
- /* if the client isn't focused, then hilite it so the user
- knows it is there */
- client_hilite(self, TRUE);
- /* we may want to raise it even tho we're not activating it */
- if (raise && !client_restore_session_stacking(self))
- stacking_raise(CLIENT_AS_WINDOW(self));
+ /* if the client isn't stealing focus, then hilite it so the user
+ knows it is there, but don't do this if we're restoring from a
+ session */
+ if (!client_restore_session_stacking(self))
+ client_hilite(self, TRUE);
}
}
else {
@@ -781,6 +676,105 @@ void client_fake_unmanage(ObClient *self)
g_free(self);
}
+static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
+ Time launch_time)
+{
+ gboolean steal;
+ gboolean relative_focused;
+ gboolean parent_focused;
+
+ steal = TRUE;
+
+ parent_focused = (focus_client != NULL &&
+ client_search_focus_parent(self));
+ relative_focused = (focus_client != NULL &&
+ (client_search_focus_tree_full(self) != NULL ||
+ client_search_focus_group_full(self) != NULL));
+
+ /* This is focus stealing prevention */
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Want to focus new window 0x%x at time %u "
+ "launched at %u (last user interaction time %u)",
+ self->window, steal_time, launch_time,
+ event_last_user_time);
+
+ /* if it's on another desktop */
+ if (!(self->desktop == screen_desktop ||
+ self->desktop == DESKTOP_ALL) &&
+ /* the timestamp is from before you changed desktops */
+ launch_time && screen_desktop_user_time &&
+ !event_time_after(launch_time, screen_desktop_user_time))
+ {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because its on another "
+ "desktop\n");
+ }
+ /* If something is focused... */
+ else if (focus_client) {
+ /* If the user is working in another window right now, then don't
+ steal focus */
+ if (!parent_focused &&
+ event_last_user_time && launch_time &&
+ event_time_after(event_last_user_time, launch_time) &&
+ event_last_user_time != launch_time &&
+ event_time_after(event_last_user_time,
+ steal_time - OB_EVENT_USER_TIME_DELAY))
+ {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because the user is "
+ "working in another window that is not "
+ "its parent");
+ }
+ /* If the new window is a transient (and its relatives aren't
+ focused) */
+ else if (client_has_parent(self) && !relative_focused) {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because it is a "
+ "transient, and its relatives aren't focused");
+ }
+ /* Don't steal focus from globally active clients.
+ I stole this idea from KWin. It seems nice.
+ */
+ else if (!(focus_client->can_focus ||
+ focus_client->focus_notify))
+ {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because a globally "
+ "active client has focus");
+ }
+ /* Don't move focus if it's not going to go to this window
+ anyway */
+ else if (client_focus_target(self) != self) {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because another window "
+ "would get the focus anyway");
+ }
+ /* Don't move focus if the window is not visible on the current
+ desktop and none of its relatives are focused */
+ else if (!(self->desktop == screen_desktop ||
+ self->desktop == DESKTOP_ALL) &&
+ !relative_focused)
+ {
+ steal = FALSE;
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Not focusing the window because it is on "
+ "another desktop and no relatives are focused ");
+ }
+ }
+
+ if (!steal)
+ ob_debug_type(OB_DEBUG_FOCUS,
+ "Focus stealing prevention activated for %s at "
+ "time %u (last user interaction time %u)",
+ self->title, steal_time, event_last_user_time);
+ return steal;
+}
+
/*! Returns a new structure containing the per-app settings for this client.
The returned structure needs to be freed with g_free. */
static ObAppSettings *client_get_settings_state(ObClient *self)
@@ -2550,10 +2544,6 @@ gboolean client_hide(ObClient *self)
gboolean hide = FALSE;
if (!client_should_show(self)) {
- if (self == focus_client) {
- event_cancel_all_key_grabs();
- }
-
/* We don't need to ignore enter events here.
The window can hide/iconify in 3 different ways:
1 - through an x message. in this case we ignore all enter events
@@ -3443,8 +3433,18 @@ void client_hilite(ObClient *self, gboolean hilite)
/* don't allow focused windows to hilite */
self->demands_attention = hilite && !client_focused(self);
if (self->frame != NULL) { /* if we're mapping, just set the state */
- if (self->demands_attention)
+ if (self->demands_attention) {
frame_flash_start(self->frame);
+
+ /* if the window is on another desktop then raise it and make it
+ the most recently used window */
+ if (self->desktop != screen_desktop &&
+ self->desktop != DESKTOP_ALL)
+ {
+ stacking_raise(CLIENT_AS_WINDOW(self));
+ focus_order_to_top(self);
+ }
+ }
else
frame_flash_stop(self->frame);
client_change_state(self);
@@ -3759,8 +3759,6 @@ gboolean client_focus(ObClient *self)
go moving on us */
event_halt_focus_delay();
- event_cancel_all_key_grabs();
-
obt_display_ignore_errors(TRUE);
if (self->can_focus) {
@@ -3819,12 +3817,16 @@ static void client_present(ObClient *self, gboolean here, gboolean raise,
}
/* this function exists to map to the net_active_window message in the ewmh */
-void client_activate(ObClient *self, gboolean here, gboolean raise,
+void client_activate(ObClient *self, gboolean desktop, gboolean raise,
gboolean unshade, gboolean user)
{
- if (user || (self->desktop == DESKTOP_ALL ||
- self->desktop == screen_desktop))
- client_present(self, here, raise, unshade);
+ if ((user && (desktop ||
+ self->desktop == DESKTOP_ALL ||
+ self->desktop == screen_desktop)) ||
+ client_can_steal_focus(self, event_curtime, CurrentTime))
+ {
+ client_present(self, FALSE, raise, unshade);
+ }
else
client_hilite(self, TRUE);
}
diff --git a/openbox/client.h b/openbox/client.h
index ca992746..30cab17b 100644
--- a/openbox/client.h
+++ b/openbox/client.h
@@ -573,14 +573,14 @@ gboolean client_focus(ObClient *self);
/*! Activates the client for use, focusing, uniconifying it, etc. To be used
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 desktop If true, and the window is on another desktop, it will still
+ be activated.
@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 raise,
+void client_activate(ObClient *self, gboolean desktop, gboolean raise,
gboolean unshade, gboolean user);
/*! Bring all of its helper windows to its desktop. These are the utility and
diff --git a/openbox/client_list_combined_menu.c b/openbox/client_list_combined_menu.c
index a04d07d6..ad23cd48 100644
--- a/openbox/client_list_combined_menu.c
+++ b/openbox/client_list_combined_menu.c
@@ -114,7 +114,7 @@ static void menu_execute(ObMenuEntry *self, ObMenuFrame *f,
else {
ObClient *t = self->data.normal.data;
if (t) { /* it's set to NULL if its destroyed */
- client_activate(t, FALSE, TRUE, TRUE, TRUE);
+ client_activate(t, TRUE, TRUE, TRUE, TRUE);
/* if the window is omnipresent then we need to go to its
desktop */
if (t->desktop == DESKTOP_ALL)
diff --git a/openbox/client_list_menu.c b/openbox/client_list_menu.c
index 4ec6e785..ca4534ba 100644
--- a/openbox/client_list_menu.c
+++ b/openbox/client_list_menu.c
@@ -101,7 +101,7 @@ static void desk_menu_execute(ObMenuEntry *self, ObMenuFrame *f,
{
ObClient *t = self->data.normal.data;
if (t) { /* it's set to NULL if its destroyed */
- client_activate(t, FALSE, TRUE, TRUE, TRUE);
+ client_activate(t, TRUE, TRUE, TRUE, TRUE);
/* if the window is omnipresent then we need to go to its
desktop */
if (t->desktop == DESKTOP_ALL)
diff --git a/openbox/event.c b/openbox/event.c
index 38b6bec2..4ddb7ac7 100644
--- a/openbox/event.c
+++ b/openbox/event.c
@@ -1329,10 +1329,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
(e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
/* XXX make use of data.l[2] !? */
if (e->xclient.data.l[0] == 1 || e->xclient.data.l[0] == 2) {
- /* don't use the user's timestamp for client_focus, cuz if it's
- an old broken timestamp (happens all the time) then focus
- won't move even though we're trying to move it
- event_curtime = e->xclient.data.l[1];*/
+ event_curtime = e->xclient.data.l[1];
if (e->xclient.data.l[1] == 0)
ob_debug_type(OB_DEBUG_APP_BUGS,
"_NET_ACTIVE_WINDOW message for window %s is"
@@ -1341,7 +1338,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", client->title);
- client_activate(client, TRUE, TRUE, TRUE,
+ client_activate(client, FALSE, TRUE, TRUE,
(e->xclient.data.l[0] == 0 ||
e->xclient.data.l[0] == 2));
} else if (msgtype == OBT_PROP_ATOM(NET_WM_MOVERESIZE)) {
diff --git a/openbox/focus.c b/openbox/focus.c
index 2af0da9c..fc0fd99b 100644
--- a/openbox/focus.c
+++ b/openbox/focus.c
@@ -83,10 +83,6 @@ void focus_set_client(ObClient *client)
screen_install_colormap(focus_client, FALSE);
screen_install_colormap(client, TRUE);
- /* in the middle of cycling..? kill it. */
- focus_cycle_stop(focus_client);
- focus_cycle_stop(client);
-
focus_client = client;
if (client != NULL) {
@@ -196,8 +192,6 @@ void focus_nothing(void)
/* nothing is focused, update the colormap and _the root property_ */
focus_set_client(NULL);
- event_cancel_all_key_grabs();
-
/* when nothing will be focused, send focus to the backup target */
XSetInputFocus(obt_display, screen_support_win, RevertToPointerRoot,
event_curtime);
diff --git a/openbox/session.c b/openbox/session.c
index d1a3f99b..758e9887 100644
--- a/openbox/session.c
+++ b/openbox/session.c
@@ -34,6 +34,7 @@ void session_startup(gint argc, gchar **argv) {}
void session_shutdown(gboolean permanent) {}
GList* session_state_find(struct _ObClient *c) { return NULL; }
void session_request_logout(gboolean silent) {}
+gboolean session_connected(void) { return FALSE; }
#else
#include "debug.h"
@@ -159,6 +160,11 @@ void session_shutdown(gboolean permanent)
}
}
+gboolean session_connected(void)
+{
+ return !!sm_conn;
+}
+
/*! Connect to the session manager and set up our callback functions */
static gboolean session_connect(void)
{
diff --git a/openbox/session.h b/openbox/session.h
index e2307a6f..f37e2111 100644
--- a/openbox/session.h
+++ b/openbox/session.h
@@ -55,4 +55,6 @@ GList* session_state_find(struct _ObClient *c);
void session_request_logout(gboolean silent);
+gboolean session_connected(void);
+
#endif