summaryrefslogtreecommitdiff
path: root/src/split.c
diff options
context:
space:
mode:
authorsabetts <sabetts>2001-04-06 07:43:17 +0000
committersabetts <sabetts>2001-04-06 07:43:17 +0000
commit4ef01dc374bd76295e7a46140591e516187e33df (patch)
tree0534514c60d47f7ed7640091840516bef51273a0 /src/split.c
parentb5272706dbd9346033add6edee2aaa519f11b182 (diff)
downloadratpoison-4ef01dc374bd76295e7a46140591e516187e33df.zip
* src/split.h (h_split_frame): renamed frome h_split_window
(v_split_frame): renamed frome v_split_window (split_frame): renamed frome split_window (remove_all_splits): renamed frome remove_all_frames (find_windows_frame): new prototype (find_frame_next): likewise (find_frame_prev): likewise (current_window): likewise (init_frame_list): likewise (set_active_frame): likewise * src/split.c (create_initial_frame): new function (init_frame_list): likewise (find_windows_frame): likewise (find_frame_next): likewise (find_frame_prev): likewise (current_window): likewise (update_frame_indicator): likewise (set_active_frame): likewise (split_frame): rename from split_window (v_split_frame): rename from v_split_window (h_split_frame): rename from h_split_window (remove_all_splits): renamed frome remove_all_frames (total_frame_area): traverses rp_window_frame list (num_frames): likewise (frame_overlaps): likewise (remove_frame): likewise (remove_frame): calls delete_frame_from_list * src/manage.c (scanwins): skips the frame_window (maximize_transient): finds the window's frame (maximize_normal): likewise * src/main.c (main): calls init_frame_list (init_screen): create and map the frame_window * src/list.c (give_window_focus): new function (goto_window): likewise (set_active_window): calls give_window_focus * src/list.h (give_window_focus): new prototype (goto_window): likewise * src/events.c (new_window): the screen's frame_window is not managed (cleanup_frame): new function (unmap_notify): calls cleanup_frame if window exists in a frame (destroy_window): likewise * src/data.h (struct screen_info): remove frame field (struct rp_window_frame): new fields win, prev, next (rp_window_frame_sentinel): new global * src/actions.c (cmd_prev): jumps to last accessed window if current frame is empty. (cmd_next): likewise (cmd_remove): nothing is done if only 1 frame exists * src/data.h (struct screen_info): new field frame_window (rp_current_frame): new global (rp_current_window): removed. All dependant code updated.
Diffstat (limited to 'src/split.c')
-rw-r--r--src/split.c420
1 files changed, 265 insertions, 155 deletions
diff --git a/src/split.c b/src/split.c
index d79903b..5c00572 100644
--- a/src/split.c
+++ b/src/split.c
@@ -23,6 +23,111 @@
#include "ratpoison.h"
+rp_window_frame *rp_window_frame_sentinel;
+rp_window_frame *rp_current_frame;
+
+static void
+delete_frame_from_list (rp_window_frame *frame)
+{
+ frame->next->prev = frame->prev;
+ frame->prev->next = frame->next;
+}
+
+/* Create a full screen frame */
+static void
+create_initial_frame ()
+{
+ screen_info *s;
+
+ s = current_screen();
+ rp_current_frame = xmalloc (sizeof (rp_window_frame));
+
+ rp_current_frame = xmalloc (sizeof (rp_window_frame));
+ rp_current_frame->x = PADDING_LEFT;
+ rp_current_frame->y = PADDING_TOP;
+
+ /* FIXME: what about multiple screens? */
+ rp_current_frame->width = DisplayWidth (dpy, 0) - PADDING_RIGHT - PADDING_LEFT;
+ rp_current_frame->height = DisplayHeight (dpy, 0) - PADDING_BOTTOM - PADDING_TOP;
+
+ rp_window_frame_sentinel->next = rp_current_frame;
+ rp_window_frame_sentinel->prev = rp_current_frame;
+ rp_current_frame->next = rp_window_frame_sentinel;
+ rp_current_frame->prev = rp_window_frame_sentinel;
+
+ rp_current_frame->win = NULL;
+}
+
+void
+init_frame_list ()
+{
+ rp_window_frame_sentinel = xmalloc (sizeof (rp_window_frame));
+
+ rp_window_frame_sentinel->next = rp_window_frame_sentinel;
+ rp_window_frame_sentinel->prev = rp_window_frame_sentinel;
+
+ create_initial_frame();
+}
+
+/* Return the frame that contains the window. */
+rp_window_frame *
+find_windows_frame (rp_window *win)
+{
+ rp_window_frame *cur;
+
+ for (cur = rp_window_frame_sentinel->next;
+ cur != rp_window_frame_sentinel;
+ cur = cur->next)
+ {
+ if (cur->win == win) return cur;
+ }
+
+ return NULL;
+}
+
+rp_window_frame *
+find_frame_next (rp_window_frame *frame)
+{
+ rp_window_frame *cur;
+
+ if (frame == NULL) return NULL;
+
+ cur = frame;
+ if (cur->next == rp_window_frame_sentinel)
+ {
+ cur = cur->next;
+ if (cur->next == frame) return NULL;
+ }
+
+ return cur->next;
+}
+
+rp_window_frame *
+find_frame_prev (rp_window_frame *frame)
+{
+ rp_window_frame *cur;
+
+ if (frame == NULL) return NULL;
+
+ cur = frame;
+ if (cur->prev == rp_window_frame_sentinel)
+ {
+ cur = cur->prev;
+ if (cur->prev == frame) return NULL;
+ }
+
+ return cur->prev;
+}
+
+rp_window *
+current_window ()
+{
+ if (rp_current_frame) return rp_current_frame->win;
+
+ PRINT_ERROR ("BUG: There should always be a current frame\n");
+ return NULL;
+}
+
static int
window_fits_in_frame (rp_window *win, rp_window_frame *frame)
{
@@ -54,8 +159,8 @@ find_window_for_frame (rp_window_frame *frame)
cur != rp_mapped_window_sentinel;
cur = cur->next)
{
- if (cur != rp_current_window
- && !cur->frame
+ if (cur != current_window()
+ && !find_windows_frame (cur)
&& cur->last_access >= last_access
&& window_fits_in_frame (cur, frame))
{
@@ -67,109 +172,110 @@ find_window_for_frame (rp_window_frame *frame)
return most_recent;
}
-/* Splits the window in 2. if way is != 0 then split it horizontally
- otherwise split it vertically. */
-static int
-split_window (rp_window *win, int way)
+static void
+update_frame_indicator ()
+{
+ XMoveWindow (dpy, current_screen()->frame_window,
+ rp_current_frame->x + rp_current_frame->width / 2 - 5,
+ rp_current_frame->y + rp_current_frame->height / 2 - 5);
+}
+
+/* Splits the frame in 2. if way is 0 then split vertically otherwise
+ split it horizontally. */
+static void
+split_frame (rp_window_frame *frame, int way)
{
- rp_window *other_window;
- rp_window_frame *frame1, *frame2;
+ rp_window *win;
+ rp_window_frame *new_frame;
- frame1 = xmalloc (sizeof (rp_window_frame));
- frame2 = xmalloc (sizeof (rp_window_frame));
+ /* You can't split a frame unless it has a window in it. */
+ if (!frame->win) return;
- if (!win->frame)
- {
- frame1->x = PADDING_LEFT;
- frame1->y = PADDING_TOP;
- frame1->width = win->scr->root_attr.width
- - PADDING_RIGHT - PADDING_LEFT;
- frame1->height = win->scr->root_attr.height
- - PADDING_BOTTOM - PADDING_TOP;
- }
- else
- {
- frame1->x = win->frame->x;
- frame1->y = win->frame->y;
- frame1->width = win->frame->width;
- frame1->height = win->frame->height;
- }
+ new_frame = xmalloc (sizeof (rp_window_frame));
+
+ /* append the new frame to the list */
+ new_frame->prev = rp_window_frame_sentinel->prev;
+ rp_window_frame_sentinel->prev->next = new_frame;
+ rp_window_frame_sentinel->prev = new_frame;
+ new_frame->next = rp_window_frame_sentinel;
if (way)
{
- frame2->x = frame1->x;
- frame2->y = frame1->y + frame1->height / 2;
- frame2->width = frame1->width;
- frame2->height = frame1->height / 2 + frame1->height % 2;
+ new_frame->x = frame->x;
+ new_frame->y = frame->y + frame->height / 2;
+ new_frame->width = frame->width;
+ new_frame->height = frame->height / 2 + frame->height % 2;
- frame1->height /= 2;
+ frame->height /= 2;
}
else
{
- frame2->x = frame1->x + frame1->width / 2;
- frame2->y = frame1->y;
- frame2->width = frame1->width / 2 + frame1->width % 2;
- frame2->height = frame1->height;
+ new_frame->x = frame->x + frame->width / 2;
+ new_frame->y = frame->y;
+ new_frame->width = frame->width / 2 + frame->width % 2;
+ new_frame->height = frame->height;
- frame1->width /= 2;
+ frame->width /= 2;
}
-
- other_window = find_window_for_frame (frame2);
- if (other_window)
+
+ win = find_window_for_frame (new_frame);
+ if (win)
{
- PRINT_DEBUG ("Split the window!\n");
+ PRINT_DEBUG ("Found a window for the frame!\n");
- if (win->frame) free (win->frame);
- win->frame = frame1;
- other_window->frame = frame2;
+ new_frame->win = win;
maximize (win);
- maximize (other_window);
- XRaiseWindow (dpy, other_window->w);
XRaiseWindow (dpy, win->w);
-
- return 1;
}
else
{
- PRINT_DEBUG ("Failed to split.\n");
+ PRINT_DEBUG ("No window fits the frame.\n");
- free (frame1);
- free (frame2);
-
- return 0;
+ new_frame->win = NULL;
}
+
+ /* resize the existing frame */
+ maximize (frame->win);
+ XRaiseWindow (dpy, frame->win->w);
+
+ update_frame_indicator();
}
/* Splits the window vertically in 2. */
-int
-v_split_window (rp_window *win)
+void
+v_split_frame (rp_window_frame *frame)
{
- return split_window (win, 0);
+ split_frame (frame, 0);
}
/* Splits the window horizontally in 2. */
-int
-h_split_window (rp_window *win)
+void
+h_split_frame (rp_window_frame *frame)
{
- return split_window (win, 1);
+ split_frame (frame, 1);
}
void
-remove_all_frames ()
+remove_all_splits ()
{
- rp_window *cur;
+ rp_window *cur_window;
+ rp_window_frame *cur;
- for (cur = rp_mapped_window_sentinel->next;
- cur != rp_mapped_window_sentinel;
- cur = cur->next)
+ cur_window = current_window();
+
+ while (rp_window_frame_sentinel->next != rp_window_frame_sentinel)
{
- if (cur->frame)
- {
- free (cur->frame);
- cur->frame = NULL;
- }
+ cur = rp_window_frame_sentinel->next;
+ delete_frame_from_list (cur);
+ free (cur);
}
+
+ create_initial_frame ();
+ rp_current_frame->win = cur_window;
+
+ maximize (cur_window);
+ XRaiseWindow (dpy, cur_window->w);
}
static int
@@ -204,16 +310,13 @@ static int
total_frame_area ()
{
int area = 0;
- rp_window *cur;
+ rp_window_frame *cur;
- for (cur = rp_mapped_window_sentinel->next;
- cur != rp_mapped_window_sentinel;
+ for (cur = rp_window_frame_sentinel->next;
+ cur != rp_window_frame_sentinel;
cur = cur->next)
{
- if (cur->frame)
- {
- area += cur->frame->width * cur->frame->height;
- }
+ area += cur->width * cur->height;
}
return area;
@@ -223,16 +326,13 @@ static int
num_frames ()
{
int count = 0;
- rp_window *cur;
+ rp_window_frame *cur;
- for (cur = rp_mapped_window_sentinel->next;
- cur != rp_mapped_window_sentinel;
+ for (cur = rp_window_frame_sentinel->next;
+ cur != rp_window_frame_sentinel;
cur = cur->next)
{
- if (cur->frame)
- {
- count++;
- }
+ count++;
}
return count;
@@ -254,17 +354,15 @@ frames_overlap (rp_window_frame *f1, rp_window_frame *f2)
/* Return 1 if w's frame overlaps any other window's frame */
static int
-frame_overlaps (rp_window *w)
+frame_overlaps (rp_window_frame *frame)
{
- rp_window *cur;
+ rp_window_frame *cur;
- for (cur = rp_mapped_window_sentinel->next;
- cur != rp_mapped_window_sentinel;
+ for (cur = rp_window_frame_sentinel->next;
+ cur != rp_window_frame_sentinel;
cur = cur->next)
{
- if (cur != w
- && cur->frame
- && frames_overlap (cur->frame, w->frame))
+ if (cur != frame && frames_overlap (cur, frame))
{
return 1;
}
@@ -273,105 +371,117 @@ frame_overlaps (rp_window *w)
}
void
-remove_frame (rp_window *w)
+remove_frame (rp_window_frame *frame)
{
int area;
- rp_window *cur;
- rp_window_frame *frame;
+ rp_window_frame *cur;
- if (w->frame == NULL) return;
+ if (frame == NULL) return;
area = total_frame_area();
PRINT_DEBUG ("Total Area: %d\n", area);
- frame = w->frame;
- w->frame = NULL;
+ delete_frame_from_list (frame);
/* If there is 1 frame then we have no split screen, so get rid
of the remaining window frame. */
if (num_frames() <= 1)
{
- remove_all_frames();
+ remove_all_splits ();
free (frame);
return;
}
- for (cur = rp_mapped_window_sentinel->next;
- cur != rp_mapped_window_sentinel;
+ for (cur = rp_window_frame_sentinel->next;
+ cur != rp_window_frame_sentinel;
cur = cur->next)
{
- if (cur->frame)
- {
- rp_window_frame tmp_frame;
- int fits = 0;
+ rp_window_frame tmp_frame;
+ int fits = 0;
- /* Backup the frame */
- memcpy (&tmp_frame, cur->frame, sizeof (rp_window_frame));
+ /* Backup the frame */
+ memcpy (&tmp_frame, cur, sizeof (rp_window_frame));
- if (frame_is_below (frame, cur->frame)
- || frame_is_above (frame, cur->frame))
- {
- if (frame_is_below (frame, cur->frame))
- cur->frame->y = frame->y;
- cur->frame->height += frame->height;
- }
+ if (frame_is_below (frame, cur)
+ || frame_is_above (frame, cur))
+ {
+ if (frame_is_below (frame, cur))
+ cur->y = frame->y;
+ cur->height += frame->height;
+ }
- PRINT_DEBUG ("New Total Area: %d\n", total_frame_area());
+ PRINT_DEBUG ("New Total Area: %d\n", total_frame_area());
- if (total_frame_area() > area || frame_overlaps (cur))
- {
- PRINT_DEBUG ("Didn't fit vertically\n");
+ if (total_frame_area() > area || frame_overlaps (cur))
+ {
+ PRINT_DEBUG ("Didn't fit vertically\n");
- /* Restore the current window's frame */
- memcpy (cur->frame, &tmp_frame, sizeof (rp_window_frame));
- }
- else
- {
- PRINT_DEBUG ("It fit vertically!!\n");
+ /* Restore the current window's frame */
+ memcpy (cur, &tmp_frame, sizeof (rp_window_frame));
+ }
+ else
+ {
+ PRINT_DEBUG ("It fit vertically!!\n");
- /* update the frame backup */
- memcpy (&tmp_frame, cur->frame, sizeof (rp_window_frame));
- fits = 1;
- }
+ /* update the frame backup */
+ memcpy (&tmp_frame, cur, sizeof (rp_window_frame));
+ fits = 1;
+ }
- if (frame_is_left (frame, cur->frame)
- || frame_is_right (frame, cur->frame))
- {
- if (frame_is_right (frame, cur->frame))
- cur->frame->x = frame->x;
- cur->frame->width += frame->width;
- }
+ if (frame_is_left (frame, cur)
+ || frame_is_right (frame, cur))
+ {
+ if (frame_is_right (frame, cur))
+ cur->x = frame->x;
+ cur->width += frame->width;
+ }
- PRINT_DEBUG ("New Total Area: %d\n", total_frame_area());
+ PRINT_DEBUG ("New Total Area: %d\n", total_frame_area());
- if (total_frame_area() > area || frame_overlaps (cur))
- {
- PRINT_DEBUG ("Didn't fit horizontally\n");
+ if (total_frame_area() > area || frame_overlaps (cur))
+ {
+ PRINT_DEBUG ("Didn't fit horizontally\n");
- /* Restore the current window's frame */
- memcpy (cur->frame, &tmp_frame, sizeof (rp_window_frame));
- }
- else
- {
- PRINT_DEBUG ("It fit horizontally!!\n");
- fits = 1;
- }
+ /* Restore the current window's frame */
+ memcpy (cur, &tmp_frame, sizeof (rp_window_frame));
+ }
+ else
+ {
+ PRINT_DEBUG ("It fit horizontally!!\n");
+ fits = 1;
+ }
- if (fits)
- {
- /* The current frame fits into the new space so keep its
- new frame parameters and maximize the window to fit
- the new frame size. */
- maximize (cur);
- XRaiseWindow (dpy, cur->w);
- }
- else
+ if (fits)
+ {
+ /* The current frame fits into the new space so keep its
+ new frame parameters and maximize the window to fit
+ the new frame size. */
+ if (cur->win)
{
- memcpy (cur->frame, &tmp_frame, sizeof (rp_window_frame));
+ maximize (cur->win);
+ XRaiseWindow (dpy, cur->win->w);
}
-
+ }
+ else
+ {
+ memcpy (cur, &tmp_frame, sizeof (rp_window_frame));
}
}
free (frame);
}
+
+void
+set_active_frame (rp_window_frame *frame)
+{
+ give_window_focus (frame->win);
+ rp_current_frame = frame;
+
+ update_frame_indicator();
+
+ if( !frame->win )
+ {
+ XSetInputFocus (dpy, current_screen()->frame_window,
+ RevertToPointerRoot, CurrentTime);
+ }
+}