[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Allow frames to be focused with the mouse



Clicking on empty frames now selects them.
---
 src/globals.h |    2 +-
 src/layout.c  |   47 ++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/src/globals.h b/src/globals.h
index ef99432..3c5cb61 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -20,7 +20,7 @@
 
 #define ROOT_EVENT_MASK (SubstructureRedirectMask|SubstructureNotifyMask|ButtonPressMask|EnterWindowMask|LeaveWindowMask|StructureNotifyMask)
 //#define CLIENT_EVENT_MASK (PropertyChangeMask | FocusChangeMask | StructureNotifyMask)
-#define CLIENT_EVENT_MASK (FocusChangeMask|EnterWindowMask|PropertyChangeMask)
+#define CLIENT_EVENT_MASK (FocusChangeMask|EnterWindowMask|PropertyChangeMask|ButtonPressMask)
 
 // minimum relative fraction of split frames
 #define FRAME_MIN_FRACTION 0.1
diff --git a/src/layout.c b/src/layout.c
index c6728b3..e72df5a 100644
--- a/src/layout.c
+++ b/src/layout.c
@@ -133,7 +133,7 @@ HSFrame* frame_create_empty(HSFrame* parent, HSTag* parenttag) {
     at.bit_gravity       = StaticGravity;
     at.event_mask        = SubstructureRedirectMask|SubstructureNotifyMask
          |ExposureMask|VisibilityChangeMask
-         |EnterWindowMask|LeaveWindowMask|FocusChangeMask;
+         |EnterWindowMask|LeaveWindowMask|FocusChangeMask|ButtonPressMask;
     frame->window = XCreateWindow(g_display, g_root,
                         42, 42, 42, 42, *g_frame_border_width,
                         DefaultDepth(g_display, DefaultScreen(g_display)),
@@ -1483,7 +1483,9 @@ bool frame_focus_window(HSFrame* frame, Window win) {
     if (!frame) {
         return false;
     }
-    if (frame->type == TYPE_CLIENTS) {
+    if (frame->window == win) {
+        return true;
+    } else if (frame->type == TYPE_CLIENTS) {
         int i;
         size_t count = frame->content.clients.count;
         Window* buf = frame->content.clients.buf;
@@ -1515,18 +1517,53 @@ bool frame_focus_window(HSFrame* frame, Window win) {
     }
 }
 
+HSFrame *get_frame_from_window_rec(HSFrame *root, Window win)
+{
+    if (root->window == win) {
+        return root;
+    } else if (root->type == TYPE_FRAMES) {
+        HSFrame *frame = get_frame_from_window_rec(root->content.layout.a, win);
+        if (frame != NULL) {
+            return frame;
+        }
+        frame = get_frame_from_window_rec(root->content.layout.b, win);
+        if (frame != NULL) {
+            return frame;
+        }
+    }
+    return NULL;
+}
+
+HSFrame *get_frame_from_window(Window win)
+{
+    for (int i = 0; i < monitor_count(); i++) {
+        HSMonitor* m = monitor_with_index(i);
+        HSFrame *f = get_frame_from_window_rec(m->tag->frame, win);
+        if (f != NULL) {
+            return f;
+        }
+    }
+    return NULL;
+}
+
 // focus a window
 // switch_tag tells, whether to switch tag to focus to window
 // switch_monitor tells, whether to switch monitor to focus to window
 // returns if window was focused or not
 bool focus_window(Window win, bool switch_tag, bool switch_monitor) {
     HSClient* client = get_client_from_window(win);
+    HSTag* tag;
     if (!client) {
         // client is not managed
-        return false;
+        HSFrame *frame = get_frame_from_window(win);
+        if (!frame) {
+            return false;
+        }
+        tag = frame->tag;
+    } else {
+        tag = client->tag;
     }
-    HSTag* tag = client->tag;
-    assert(client->tag);
+    assert(tag);
     HSMonitor* monitor = find_monitor_with_tag(tag);
     HSMonitor* cur_mon = get_current_monitor();
     if (monitor != cur_mon && !switch_monitor) {
-- 
1.7.8.6