more focus improvements. everything seems to work!
This commit is contained in:
parent
d82048b4e5
commit
3b14b587ef
5 changed files with 67 additions and 60 deletions
|
@ -239,17 +239,6 @@ void client_unmanage(Client *client)
|
||||||
|
|
||||||
engine_frame_hide(client->frame);
|
engine_frame_hide(client->frame);
|
||||||
|
|
||||||
/* dispatch the unmapped event */
|
|
||||||
dispatch_client(Event_Client_Unmapped, client, 0, 0);
|
|
||||||
g_assert(client != NULL);
|
|
||||||
|
|
||||||
/* give the client its border back */
|
|
||||||
client_toggle_border(client, TRUE);
|
|
||||||
|
|
||||||
/* reparent the window out of the frame, and free the frame */
|
|
||||||
engine_frame_release_client(client->frame, client);
|
|
||||||
client->frame = NULL;
|
|
||||||
|
|
||||||
client_list = g_slist_remove(client_list, client);
|
client_list = g_slist_remove(client_list, client);
|
||||||
stacking_list = g_list_remove(stacking_list, client);
|
stacking_list = g_list_remove(stacking_list, client);
|
||||||
g_hash_table_remove(client_map, (gpointer)client->window);
|
g_hash_table_remove(client_map, (gpointer)client->window);
|
||||||
|
@ -278,11 +267,22 @@ void client_unmanage(Client *client)
|
||||||
client_calc_layer(it->data);
|
client_calc_layer(it->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dispatch the unmapped event */
|
||||||
|
dispatch_client(Event_Client_Unmapped, client, 0, 0);
|
||||||
|
g_assert(client != NULL);
|
||||||
|
|
||||||
/* unfocus the client (dispatchs the focus event) (we're out of the
|
/* unfocus the client (dispatchs the focus event) (we're out of the
|
||||||
transient lists already, so being modal doesn't matter) */
|
transient lists already, so being modal doesn't matter) */
|
||||||
if (client_focused(client))
|
if (client_focused(client))
|
||||||
client_unfocus(client);
|
client_unfocus(client);
|
||||||
|
|
||||||
|
/* give the client its border back */
|
||||||
|
client_toggle_border(client, TRUE);
|
||||||
|
|
||||||
|
/* reparent the window out of the frame, and free the frame */
|
||||||
|
engine_frame_release_client(client->frame, client);
|
||||||
|
client->frame = NULL;
|
||||||
|
|
||||||
if (ob_state != State_Exiting) {
|
if (ob_state != State_Exiting) {
|
||||||
/* these values should not be persisted across a window
|
/* these values should not be persisted across a window
|
||||||
unmapping/mapping */
|
unmapping/mapping */
|
||||||
|
@ -1511,6 +1511,9 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
|
||||||
client_change_state(self);
|
client_change_state(self);
|
||||||
client_showhide(self);
|
client_showhide(self);
|
||||||
screen_update_struts();
|
screen_update_struts();
|
||||||
|
|
||||||
|
dispatch_client(iconic ? Event_Client_Unmapped : Event_Client_Mapped,
|
||||||
|
self, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
|
void client_maximize(Client *self, gboolean max, int dir, gboolean savearea)
|
||||||
|
@ -1650,7 +1653,7 @@ void client_close(Client *self)
|
||||||
ce.xclient.window = self->window;
|
ce.xclient.window = self->window;
|
||||||
ce.xclient.format = 32;
|
ce.xclient.format = 32;
|
||||||
ce.xclient.data.l[0] = prop_atoms.wm_delete_window;
|
ce.xclient.data.l[0] = prop_atoms.wm_delete_window;
|
||||||
ce.xclient.data.l[1] = CurrentTime;
|
ce.xclient.data.l[1] = event_lasttime;
|
||||||
ce.xclient.data.l[2] = 0l;
|
ce.xclient.data.l[2] = 0l;
|
||||||
ce.xclient.data.l[3] = 0l;
|
ce.xclient.data.l[3] = 0l;
|
||||||
ce.xclient.data.l[4] = 0l;
|
ce.xclient.data.l[4] = 0l;
|
||||||
|
@ -1902,11 +1905,11 @@ gboolean client_focus(Client *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_focused(self))
|
g_message("** focusing %lx", self->window);
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (self->can_focus)
|
if (self->can_focus)
|
||||||
XSetInputFocus(ob_display, self->window, RevertToNone, CurrentTime);
|
XSetInputFocus(ob_display, self->window, RevertToNone,
|
||||||
|
CurrentTime);
|
||||||
|
|
||||||
if (self->focus_notify) {
|
if (self->focus_notify) {
|
||||||
XEvent ce;
|
XEvent ce;
|
||||||
|
@ -1916,7 +1919,7 @@ gboolean client_focus(Client *self)
|
||||||
ce.xclient.window = self->window;
|
ce.xclient.window = self->window;
|
||||||
ce.xclient.format = 32;
|
ce.xclient.format = 32;
|
||||||
ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
|
ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
|
||||||
ce.xclient.data.l[1] = event_lasttime;
|
ce.xclient.data.l[1] = CurrentTime;
|
||||||
ce.xclient.data.l[2] = 0l;
|
ce.xclient.data.l[2] = 0l;
|
||||||
ce.xclient.data.l[3] = 0l;
|
ce.xclient.data.l[3] = 0l;
|
||||||
ce.xclient.data.l[4] = 0l;
|
ce.xclient.data.l[4] = 0l;
|
||||||
|
@ -1930,10 +1933,26 @@ gboolean client_focus(Client *self)
|
||||||
void client_unfocus(Client *self)
|
void client_unfocus(Client *self)
|
||||||
{
|
{
|
||||||
g_assert(focus_client == self);
|
g_assert(focus_client == self);
|
||||||
focus_set_client(NULL);
|
client_set_focused(self, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean client_focused(Client *self)
|
gboolean client_focused(Client *self)
|
||||||
{
|
{
|
||||||
return self == focus_client;
|
return self == focus_client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void client_set_focused(Client *self, gboolean focused)
|
||||||
|
{
|
||||||
|
if (focused) {
|
||||||
|
if (focus_client != self)
|
||||||
|
focus_set_client(self);
|
||||||
|
} else {
|
||||||
|
if (focus_client == self)
|
||||||
|
focus_set_client(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* focus state can affect the stacking layer */
|
||||||
|
client_calc_layer(self);
|
||||||
|
|
||||||
|
engine_frame_adjust_focus(self->frame);
|
||||||
|
}
|
||||||
|
|
|
@ -320,6 +320,11 @@ gboolean client_normal(Client *self);
|
||||||
/* Returns if the window is focused */
|
/* Returns if the window is focused */
|
||||||
gboolean client_focused(Client *self);
|
gboolean client_focused(Client *self);
|
||||||
|
|
||||||
|
/*! Sets the client to a focused or unfocused state. This does not actually
|
||||||
|
change the input focus, but rather is used once focus has been moved to tell
|
||||||
|
the client that it is so. */
|
||||||
|
void client_set_focused(Client *self, gboolean focused);
|
||||||
|
|
||||||
/*! Move and/or resize the window.
|
/*! Move and/or resize the window.
|
||||||
This also maintains things like the client's minsize, and size increments.
|
This also maintains things like the client's minsize, and size increments.
|
||||||
@param anchor The corner to keep in the same position when resizing.
|
@param anchor The corner to keep in the same position when resizing.
|
||||||
|
|
|
@ -18,9 +18,11 @@ typedef enum {
|
||||||
Event_X_Bell = 1 << 7, /* an XKB bell event */
|
Event_X_Bell = 1 << 7, /* an XKB bell event */
|
||||||
|
|
||||||
Event_Client_New = 1 << 8, /* new window, before mapping */
|
Event_Client_New = 1 << 8, /* new window, before mapping */
|
||||||
Event_Client_Mapped = 1 << 9, /* new window, after mapping */
|
Event_Client_Mapped = 1 << 9, /* new window, after mapping
|
||||||
|
or uniconified */
|
||||||
Event_Client_Destroy = 1 << 10, /* unmanaged */
|
Event_Client_Destroy = 1 << 10, /* unmanaged */
|
||||||
Event_Client_Unmapped = 1 << 11, /* unmanaged, after unmapping */
|
Event_Client_Unmapped = 1 << 11, /* unmanaged, after unmapping
|
||||||
|
or iconified */
|
||||||
Event_Client_Focus = 1 << 12, /* focused */
|
Event_Client_Focus = 1 << 12, /* focused */
|
||||||
Event_Client_Unfocus = 1 << 13, /* unfocused */
|
Event_Client_Unfocus = 1 << 13, /* unfocused */
|
||||||
Event_Client_Urgent = 1 << 14, /* entered/left urgent state */
|
Event_Client_Urgent = 1 << 14, /* entered/left urgent state */
|
||||||
|
|
|
@ -219,36 +219,31 @@ void event_process(XEvent *e)
|
||||||
event_lasttime = e->xproperty.time;
|
event_lasttime = e->xproperty.time;
|
||||||
break;
|
break;
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
if (e->xfocus.mode == NotifyGrab) return;
|
if (e->xfocus.mode == NotifyGrab ||
|
||||||
/* if (e->type == FocusIn && window == focus_backup && focus_client != NULL) {
|
!(e->xfocus.detail == NotifyNonlinearVirtual ||
|
||||||
*/
|
e->xfocus.detail == NotifyNonlinear))
|
||||||
/* Something's focused but we got a focus event for the backup
|
|
||||||
window. this means that something unfocused before we received
|
|
||||||
the new FocusIn. Just ignore it, and refocus what should be
|
|
||||||
focused! */
|
|
||||||
/* client_focus(focus_client);
|
|
||||||
return;
|
return;
|
||||||
}
|
g_message("FOCUS IN %lx", window);
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
if (e->xfocus.mode == NotifyGrab) return;
|
if (e->xfocus.mode == NotifyGrab ||
|
||||||
/*|| e.xfocus.mode == NotifyUngrab ||*/
|
!(e->xfocus.detail == NotifyNonlinearVirtual ||
|
||||||
/* From Metacity, from WindowMaker, ignore all funky pointer
|
e->xfocus.detail == NotifyNonlinear))
|
||||||
root events. Its commented out cuz I don't think we need this
|
return;
|
||||||
at all. If problems arise we can look into it */
|
|
||||||
/*e.xfocus.detail > NotifyNonlinearVirtual) */
|
|
||||||
|
|
||||||
/* FocusOut events just make us look for FocusIn events. They
|
/* FocusOut events just make us look for FocusIn events. They
|
||||||
are mostly ignored otherwise. */
|
are mostly ignored otherwise. */
|
||||||
{
|
{
|
||||||
XEvent fi;
|
XEvent fi;
|
||||||
if (XCheckTypedEvent(ob_display, FocusIn, &fi)) {
|
if (XCheckTypedEvent(ob_display, FocusIn, &fi)) {
|
||||||
|
g_message("FOCUS OUT %lx IN %lx", e->xfocus.window, fi.xfocus.window);
|
||||||
event_process(&fi);
|
event_process(&fi);
|
||||||
/* dont unfocus the window we just focused! */
|
|
||||||
if (fi.xfocus.window == e->xfocus.window)
|
if (fi.xfocus.window == e->xfocus.window)
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
|
g_message("FOCUS OUT %lx IN 0x0", e->xfocus.window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
|
@ -334,22 +329,8 @@ static void event_handle_client(Client *client, XEvent *e)
|
||||||
|
|
||||||
switch (e->type) {
|
switch (e->type) {
|
||||||
case FocusIn:
|
case FocusIn:
|
||||||
if (focus_client != client)
|
|
||||||
focus_set_client(client);
|
|
||||||
|
|
||||||
/* focus state can affect the stacking layer */
|
|
||||||
client_calc_layer(client);
|
|
||||||
|
|
||||||
engine_frame_adjust_focus(client->frame);
|
|
||||||
break;
|
|
||||||
case FocusOut:
|
case FocusOut:
|
||||||
if (focus_client == client)
|
client_set_focused(client, e->type == FocusIn);
|
||||||
focus_set_client(NULL);
|
|
||||||
|
|
||||||
/* focus state can affect the stacking layer */
|
|
||||||
client_calc_layer(client);
|
|
||||||
|
|
||||||
engine_frame_adjust_focus(client->frame);
|
|
||||||
break;
|
break;
|
||||||
case ConfigureRequest:
|
case ConfigureRequest:
|
||||||
g_message("ConfigureRequest for window %lx", client->window);
|
g_message("ConfigureRequest for window %lx", client->window);
|
||||||
|
@ -508,7 +489,7 @@ static void event_handle_client(Client *client, XEvent *e)
|
||||||
client_set_desktop(client, e->xclient.data.l[0]);
|
client_set_desktop(client, e->xclient.data.l[0]);
|
||||||
} else if (msgtype == prop_atoms.net_wm_state) {
|
} else if (msgtype == prop_atoms.net_wm_state) {
|
||||||
/* can't compress these */
|
/* can't compress these */
|
||||||
g_message("net_wm_state %s %ld %ld for 0x%lx\n",
|
g_message("net_wm_state %s %ld %ld for 0x%lx",
|
||||||
(e->xclient.data.l[0] == 0 ? "Remove" :
|
(e->xclient.data.l[0] == 0 ? "Remove" :
|
||||||
e->xclient.data.l[0] == 1 ? "Add" :
|
e->xclient.data.l[0] == 1 ? "Add" :
|
||||||
e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),
|
e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),
|
||||||
|
@ -517,10 +498,10 @@ static void event_handle_client(Client *client, XEvent *e)
|
||||||
client_set_state(client, e->xclient.data.l[0],
|
client_set_state(client, e->xclient.data.l[0],
|
||||||
e->xclient.data.l[1], e->xclient.data.l[2]);
|
e->xclient.data.l[1], e->xclient.data.l[2]);
|
||||||
} else if (msgtype == prop_atoms.net_close_window) {
|
} else if (msgtype == prop_atoms.net_close_window) {
|
||||||
g_message("net_close_window for 0x%lx\n", client->window);
|
g_message("net_close_window for 0x%lx", client->window);
|
||||||
client_close(client);
|
client_close(client);
|
||||||
} else if (msgtype == prop_atoms.net_active_window) {
|
} else if (msgtype == prop_atoms.net_active_window) {
|
||||||
g_message("net_active_window for 0x%lx\n", client->window);
|
g_message("net_active_window for 0x%lx", client->window);
|
||||||
if (screen_showing_desktop)
|
if (screen_showing_desktop)
|
||||||
screen_show_desktop(FALSE);
|
screen_show_desktop(FALSE);
|
||||||
if (client->iconic)
|
if (client->iconic)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
#include "event.h"
|
||||||
#include "openbox.h"
|
#include "openbox.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "prop.h"
|
#include "prop.h"
|
||||||
#include "dispatch.h"
|
#include "dispatch.h"
|
||||||
|
#include "focus.h"
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
@ -13,8 +15,6 @@ GList **focus_order = NULL; /* these lists are created when screen_startup
|
||||||
|
|
||||||
Window focus_backup = None;
|
Window focus_backup = None;
|
||||||
|
|
||||||
void focus_set_client(Client *client);
|
|
||||||
|
|
||||||
void focus_startup()
|
void focus_startup()
|
||||||
{
|
{
|
||||||
/* create the window which gets focus when no clients get it. Have to
|
/* create the window which gets focus when no clients get it. Have to
|
||||||
|
@ -62,7 +62,7 @@ void focus_set_client(Client *client)
|
||||||
|
|
||||||
if (client == NULL) {
|
if (client == NULL) {
|
||||||
/* when nothing will be focused, send focus to the backup target */
|
/* when nothing will be focused, send focus to the backup target */
|
||||||
XSetInputFocus(ob_display, focus_backup, RevertToNone, CurrentTime);
|
XSetInputFocus(ob_display, focus_backup, RevertToNone, event_lasttime);
|
||||||
}
|
}
|
||||||
|
|
||||||
old = focus_client;
|
old = focus_client;
|
||||||
|
|
Loading…
Reference in a new issue