focusup and friends on multihead setups

Torbjörn Söderstedt <[email protected]>
Newsgroups gmane.comp.window-managers.ratpoison.devel
Message-ID <[email protected]>
I have now returned to Ratpoison one more time, and decided to fix the
multi-head issues that got me to abandon it the last time. It sure feels good to
be back!

The focusup/left/down/right commands are currently restricted to one screen. I
have attached a patch makes these commands move focus to the next screen when
the current frame is at the edge of the current screen. The exchange* commands
should do the same, but I didn't attempt to implement that. I thought I'd ask
about your opinion on this first.

_______________________________________________
Ratpoison-devel mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/ratpoison-devel
0001-Allow-focusup-and-friends-move-focus-to-a-different.patch (text/x-diff, 9 KB)
From 5f96d90e6c3a6fab85727809f66cc778ae1d87ba Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Torbj=C3=B6rn=20S=C3=B6derstedt?= <[email protected]>
Date: Sat, 26 Sep 2009 18:20:41 +0200
Subject: [PATCH] Allow focusup and friends move focus to a different screen.

---
 src/actions.c |   24 +++++-----
 src/split.c   |  144 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/split.h   |    8 ++--
 3 files changed, 152 insertions(+), 24 deletions(-)

diff --git a/src/actions.c b/src/actions.c
index b9116dd..02e95db 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -4239,8 +4239,8 @@ cmd_focusup (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_up (current_frame())))
-    set_active_frame (frame, 0);
+  if ((frame = find_frame_up (current_frame(), 1)))
+    set_active_frame (frame, 1);
   else
     show_frame_indicator(0);
 
@@ -4252,8 +4252,8 @@ cmd_focusdown (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_down (current_frame())))
-    set_active_frame (frame, 0);
+  if ((frame = find_frame_down (current_frame(), 1)))
+    set_active_frame (frame, 1);
   else
     show_frame_indicator(0);
 
@@ -4265,8 +4265,8 @@ cmd_focusleft (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_left (current_frame())))
-    set_active_frame (frame, 0);
+  if ((frame = find_frame_left (current_frame(), 1)))
+    set_active_frame (frame, 1);
   else
     show_frame_indicator(0);
 
@@ -4278,8 +4278,8 @@ cmd_focusright (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_right (current_frame())))
-    set_active_frame (frame, 0);
+  if ((frame = find_frame_right (current_frame(), 1)))
+    set_active_frame (frame, 1);
   else
     show_frame_indicator(0);
 
@@ -4291,7 +4291,7 @@ cmd_exchangeup (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_up (current_frame())))
+  if ((frame = find_frame_up (current_frame(), 0)))
     exchange_with_frame (current_screen(), current_frame(), frame);
 
   return cmdret_new (RET_SUCCESS, NULL);
@@ -4302,7 +4302,7 @@ cmd_exchangedown (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_down (current_frame())))
+  if ((frame = find_frame_down (current_frame(), 0)))
     exchange_with_frame (current_screen(), current_frame(), frame);
 
   return cmdret_new (RET_SUCCESS, NULL);
@@ -4313,7 +4313,7 @@ cmd_exchangeleft (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_left (current_frame())))
+  if ((frame = find_frame_left (current_frame(), 0)))
     exchange_with_frame (current_screen(), current_frame(), frame);
 
   return cmdret_new (RET_SUCCESS, NULL);
@@ -4324,7 +4324,7 @@ cmd_exchangeright (int interactive UNUSED, struct cmdarg **args UNUSED)
 {
   rp_frame *frame;
 
-  if ((frame = find_frame_right (current_frame())))
+  if ((frame = find_frame_right (current_frame(), 0)))
     exchange_with_frame (current_screen(), current_frame(), frame);
 
   return cmdret_new (RET_SUCCESS, NULL);
diff --git a/src/split.c b/src/split.c
index fa6e08f..167769d 100644
--- a/src/split.c
+++ b/src/split.c
@@ -1025,10 +1025,13 @@ show_frame_message (char *msg)
 }
 
 rp_frame *
-find_frame_up (rp_frame *frame)
+find_frame_up (rp_frame *frame, int all_screens)
 {
   rp_screen *s = frames_screen (frame);
   rp_frame *cur;
+  rp_frame *candidate = NULL;
+  int candidate_x = 0;
+  int i;
 
   list_for_each_entry (cur, &s->frames, node)
     {
@@ -1039,14 +1042,46 @@ find_frame_up (rp_frame *frame)
         }
     }
 
-  return NULL;
+  if (!all_screens)
+    return NULL;
+
+  for (i = 0; i < num_screens; i++)
+    {
+      rp_screen *s2 = &screens[i];
+
+      if (s2->top + s2->height == s->top)
+        {
+          list_for_each_entry (cur, &s2->frames, node)
+            {
+              if (cur->y + cur->height == screen_height (s2))
+                {
+                  int dx = screen_left (s) + frame->x - (screen_left (s2) + cur->x);
+                  dx = dx > 0 ? (dx >= cur->width ? dx - cur->width + 1 : 0) : abs (dx);
+                  if (candidate == NULL || dx < candidate_x)
+                    {
+                      if (dx == 0)
+                        {
+                          return cur;
+                        }
+                      candidate = cur;
+                      candidate_x = dx;
+                    }
+                }
+            }
+        }
+    }
+
+  return candidate;
 }
 
 rp_frame *
-find_frame_down (rp_frame *frame)
+find_frame_down (rp_frame *frame, int all_screens)
 {
   rp_screen *s = frames_screen (frame);
   rp_frame *cur;
+  rp_frame *candidate = NULL;
+  int candidate_x = 0;
+  int i;
 
   list_for_each_entry (cur, &s->frames, node)
     {
@@ -1057,14 +1092,46 @@ find_frame_down (rp_frame *frame)
         }
     }
 
-  return NULL;
+  if (!all_screens)
+    return NULL;
+
+  for (i = 0; i < num_screens; i++)
+    {
+      rp_screen *s2 = &screens[i];
+
+      if (s2->top == s->top + s->height)
+        {
+          list_for_each_entry (cur, &s2->frames, node)
+            {
+              if (cur->y == 0)
+                {
+                  int dx = screen_left (s) + frame->x - (screen_left (s2) + cur->x);
+                  dx = dx > 0 ? (dx >= cur->width ? dx - cur->width + 1 : 0) : abs (dx);
+                  if (candidate == NULL || dx < candidate_x)
+                    {
+                      if (dx == 0)
+                        {
+                          return cur;
+                        }
+                      candidate = cur;
+                      candidate_x = dx;
+                    }
+                }
+            }
+        }
+    }
+
+  return candidate;
 }
 
 rp_frame *
-find_frame_left (rp_frame *frame)
+find_frame_left (rp_frame *frame, int all_screens)
 {
   rp_screen *s = frames_screen (frame);
   rp_frame *cur;
+  rp_frame *candidate = NULL;
+  int candidate_y = 0;
+  int i;
 
   list_for_each_entry (cur, &s->frames, node)
     {
@@ -1075,14 +1142,46 @@ find_frame_left (rp_frame *frame)
         }
     }
 
-  return NULL;
+  if (!all_screens)
+    return NULL;
+
+  for (i = 0; i < num_screens; i++)
+    {
+      rp_screen *s2 = &screens[i];
+
+      if (s2->left + s2->width == s->left)
+        {
+          list_for_each_entry (cur, &s2->frames, node)
+            {
+              if (cur->x + cur->width == screen_width (s2))
+                {
+                  int dy = screen_top (s) + frame->y - (screen_top (s2) + cur->y);
+                  dy = dy > 0 ? (dy >= cur->height ? dy - cur->height + 1 : 0) : abs (dy);
+                  if (candidate == NULL || dy < candidate_y)
+                    {
+                      if (dy == 0)
+                        {
+                          return cur;
+                        }
+                      candidate = cur;
+                      candidate_y = dy;
+                    }
+                }
+            }
+        }
+    }
+
+  return candidate;
 }
 
 rp_frame *
-find_frame_right (rp_frame *frame)
+find_frame_right (rp_frame *frame, int all_screens)
 {
   rp_screen *s = frames_screen (frame);
   rp_frame *cur;
+  rp_frame *candidate = NULL;
+  int candidate_y = 0;
+  int i;
 
   list_for_each_entry (cur, &s->frames, node)
     {
@@ -1093,7 +1192,36 @@ find_frame_right (rp_frame *frame)
         }
     }
 
-  return NULL;
+  if (!all_screens)
+    return NULL;
+
+  for (i = 0; i < num_screens; i++)
+    {
+      rp_screen *s2 = &screens[i];
+
+      if (s2->left == s->left + s->width)
+        {
+          list_for_each_entry (cur, &s2->frames, node)
+            {
+              if (cur->x == 0)
+                {
+                  int dy = screen_top (s) + frame->y - (screen_top (s2) + cur->y);
+                  dy = dy > 0 ? (dy >= cur->height ? dy - cur->height + 1 : 0) : abs (dy);
+                  if (candidate == NULL || dy < candidate_y)
+                    {
+                      if (dy == 0)
+                        {
+                          return cur;
+                        }
+                      candidate = cur;
+                      candidate_y = dy;
+                    }
+                }
+            }
+        }
+    }
+
+  return candidate;
 }
 
 rp_frame *
diff --git a/src/split.h b/src/split.h
index 8332037..eb2fe54 100644
--- a/src/split.h
+++ b/src/split.h
@@ -48,10 +48,10 @@ void hide_frame_indicator (void);
 
 void show_frame_message (char *msg);
 
-rp_frame *find_frame_right (rp_frame *frame);
-rp_frame *find_frame_left (rp_frame *frame);
-rp_frame *find_frame_down (rp_frame *frame);
-rp_frame *find_frame_up (rp_frame *frame);
+rp_frame *find_frame_right (rp_frame *frame, int all_screens);
+rp_frame *find_frame_left (rp_frame *frame, int all_screens);
+rp_frame *find_frame_down (rp_frame *frame, int all_screens);
+rp_frame *find_frame_up (rp_frame *frame, int all_screens);
 rp_frame *find_last_frame (void);
 rp_frame * find_frame_number (int num);
 
-- 
1.6.0.4
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.