2zw - X11 Windowmanager
Files | Log | Commits | Refs | README
Author: erikbackman
Date: 2024-02-21
Subject: focus the correct window when destroying the current one
commit d1cfd19c3cf1dd2c3e1bdf71ed0df1b3ecacb5b3 Author: erikbackman <erikbackman@users.noreply.github.com> Date: Wed Feb 21 00:44:09 2024 +0100 focus the correct window when destroying the current one diff --git a/src/main.zig b/src/main.zig index 605afeb..3c78a73 100644 --- a/src/main.zig +++ b/src/main.zig @@ -97,6 +97,9 @@ var display: *C.Display = undefined; var root: C.Window = undefined; var mouse: C.XButtonEvent = undefined; var window_changes: C.XWindowChanges = undefined; +// IMPROVE: Keeping a pointer to previously_focused window as the previs node in the window list +// may or may not be the previously focused one. +var previously_focused: ?*L.Node = undefined; // Clients are kept in a doubly-linked list const L = std.DoublyLinkedList(Client); @@ -157,9 +160,11 @@ fn focus(node: *L.Node) void { C.RevertToParent, C.CurrentTime, ); + _ = C.XRaiseWindow(display, node.data.w); _ = C.XSetWindowBorder(display, node.data.w, FOCUS_BORDER_COLOR); + previously_focused = cursor; cursor = node; } @@ -183,11 +188,12 @@ fn unmanage(allocator: std.mem.Allocator, node: *L.Node, destroyed: bool) void { _ = C.XUngrabServer(display); } if (node == cursor) cursor = node.prev; - - list.remove(node); - allocator.destroy(node); - - if (cursor) |c| focus(c) else { + // IMPROVE: There is no way of determining if a window is still alive so we have to make sure we set + // previously_focused to null if we destroy it. Another way is to set an error handler to handle + // BadWindow errors if we ever try to access it. + if (previously_focused) |pf| { + if (pf.data.w == node.data.w) previously_focused = null; + } else { _ = C.XSetInputFocus( display, root, @@ -195,6 +201,9 @@ fn unmanage(allocator: std.mem.Allocator, node: *L.Node, destroyed: bool) void { C.CurrentTime, ); } + + list.remove(node); + allocator.destroy(node); } // Event handlers