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:
commit
2f09e0ce38
12 changed files with 162 additions and 148 deletions
|
@ -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 \
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
250
openbox/client.c
250
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -55,4 +55,6 @@ GList* session_state_find(struct _ObClient *c);
|
|||
|
||||
void session_request_logout(gboolean silent);
|
||||
|
||||
gboolean session_connected(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue