Merge branch 'backport' into work

Conflicts:

	openbox/actions/all.h
	openbox/actions/session.c
	openbox/client.c
	openbox/event.c
	openbox/grab.c
This commit is contained in:
Dana Jansens 2009-12-08 14:19:04 -05:00
commit 2f09e0ce38
12 changed files with 162 additions and 148 deletions

View file

@ -187,7 +187,6 @@ openbox_openbox_SOURCES = \
openbox/actions/if.c \
openbox/actions/kill.c \
openbox/actions/layer.c \
openbox/actions/session.c \
openbox/actions/lower.c \
openbox/actions/maximize.c \
openbox/actions/move.c \

View file

@ -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();

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)) {

View file

@ -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);

View file

@ -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)
{

View file

@ -55,4 +55,6 @@ GList* session_state_find(struct _ObClient *c);
void session_request_logout(gboolean silent);
gboolean session_connected(void);
#endif