all repos — openbox @ 3b14b587ef8131cbeb2afb2c11240f50c5f5d02b

openbox fork - make it a bit more like ryudo

more focus improvements. everything seems to work!
Dana Jansens danakj@orodu.net
commit

3b14b587ef8131cbeb2afb2c11240f50c5f5d02b

parent

d82048b4e515303673edf853cc64dd585f0b310a

5 files changed, 67 insertions(+), 60 deletions(-)

jump to
M openbox/client.copenbox/client.c

@@ -239,17 +239,6 @@ XSelectInput(ob_display, client->window, NoEventMask);

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); stacking_list = g_list_remove(stacking_list, client); g_hash_table_remove(client_map, (gpointer)client->window);

@@ -278,11 +267,22 @@ ((Client*)it->data)->transient_for = NULL;

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 transient lists already, so being modal doesn't matter) */ if (client_focused(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) { /* these values should not be persisted across a window unmapping/mapping */

@@ -1511,6 +1511,9 @@ }

client_change_state(self); client_showhide(self); 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)

@@ -1650,7 +1653,7 @@ ce.xclient.display = ob_display;

ce.xclient.window = self->window; ce.xclient.format = 32; 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[3] = 0l; ce.xclient.data.l[4] = 0l;

@@ -1902,11 +1905,11 @@ return FALSE;

} } - if (client_focused(self)) - return TRUE; + g_message("** focusing %lx", self->window); if (self->can_focus) - XSetInputFocus(ob_display, self->window, RevertToNone, CurrentTime); + XSetInputFocus(ob_display, self->window, RevertToNone, + CurrentTime); if (self->focus_notify) { XEvent ce;

@@ -1916,7 +1919,7 @@ ce.xclient.display = ob_display;

ce.xclient.window = self->window; ce.xclient.format = 32; 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[3] = 0l; ce.xclient.data.l[4] = 0l;

@@ -1930,10 +1933,26 @@

void client_unfocus(Client *self) { g_assert(focus_client == self); - focus_set_client(NULL); + client_set_focused(self, FALSE); } gboolean client_focused(Client *self) { 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); +}
M openbox/client.hopenbox/client.h

@@ -320,6 +320,11 @@

/* Returns if the window is focused */ 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. This also maintains things like the client's minsize, and size increments. @param anchor The corner to keep in the same position when resizing.
M openbox/dispatch.hopenbox/dispatch.h

@@ -18,9 +18,11 @@ Event_X_MotionNotify = 1 << 6, /* mouse motion */

Event_X_Bell = 1 << 7, /* an XKB bell event */ 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_Unmapped = 1 << 11, /* unmanaged, after unmapping */ + Event_Client_Unmapped = 1 << 11, /* unmanaged, after unmapping + or iconified */ Event_Client_Focus = 1 << 12, /* focused */ Event_Client_Unfocus = 1 << 13, /* unfocused */ Event_Client_Urgent = 1 << 14, /* entered/left urgent state */
M openbox/event.copenbox/event.c

@@ -219,36 +219,31 @@ case PropertyNotify:

event_lasttime = e->xproperty.time; break; case FocusIn: - if (e->xfocus.mode == NotifyGrab) return; -/* if (e->type == FocusIn && window == focus_backup && focus_client != NULL) { -*/ - /* 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); + if (e->xfocus.mode == NotifyGrab || + !(e->xfocus.detail == NotifyNonlinearVirtual || + e->xfocus.detail == NotifyNonlinear)) return; - } -*/ + g_message("FOCUS IN %lx", window); break; case FocusOut: - if (e->xfocus.mode == NotifyGrab) return; - /*|| e.xfocus.mode == NotifyUngrab ||*/ - /* From Metacity, from WindowMaker, ignore all funky pointer - root events. Its commented out cuz I don't think we need this - at all. If problems arise we can look into it */ - /*e.xfocus.detail > NotifyNonlinearVirtual) */ + if (e->xfocus.mode == NotifyGrab || + !(e->xfocus.detail == NotifyNonlinearVirtual || + e->xfocus.detail == NotifyNonlinear)) + return; /* FocusOut events just make us look for FocusIn events. They are mostly ignored otherwise. */ { XEvent fi; if (XCheckTypedEvent(ob_display, FocusIn, &fi)) { + g_message("FOCUS OUT %lx IN %lx", e->xfocus.window, fi.xfocus.window); event_process(&fi); - /* dont unfocus the window we just focused! */ - if (fi.xfocus.window == e->xfocus.window) - return; - } + + if (fi.xfocus.window == e->xfocus.window) + return; + } else { + g_message("FOCUS OUT %lx IN 0x0", e->xfocus.window); + } } break; case EnterNotify:

@@ -334,22 +329,8 @@ Atom msgtype;

switch (e->type) { 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: - if (focus_client == client) - focus_set_client(NULL); - - /* focus state can affect the stacking layer */ - client_calc_layer(client); - - engine_frame_adjust_focus(client->frame); + client_set_focused(client, e->type == FocusIn); break; case ConfigureRequest: g_message("ConfigureRequest for window %lx", client->window);

@@ -508,7 +489,7 @@ }

client_set_desktop(client, e->xclient.data.l[0]); } else if (msgtype == prop_atoms.net_wm_state) { /* 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] == 1 ? "Add" : e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),

@@ -517,10 +498,10 @@ client->window);

client_set_state(client, e->xclient.data.l[0], e->xclient.data.l[1], e->xclient.data.l[2]); } 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); } 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) screen_show_desktop(FALSE); if (client->iconic)
M openbox/focus.copenbox/focus.c

@@ -1,8 +1,10 @@

+#include "event.h" #include "openbox.h" #include "client.h" #include "screen.h" #include "prop.h" #include "dispatch.h" +#include "focus.h" #include <X11/Xlib.h> #include <glib.h>

@@ -12,8 +14,6 @@ GList **focus_order = NULL; /* these lists are created when screen_startup

sets the number of desktops */ Window focus_backup = None; - -void focus_set_client(Client *client); void focus_startup() {

@@ -62,7 +62,7 @@

if (client == NULL) { /* 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;