summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/actions.c92
-rw-r--r--src/data.h15
-rw-r--r--src/events.c12
-rw-r--r--src/frame.c41
-rw-r--r--src/frame.h2
-rw-r--r--src/manage.c34
-rw-r--r--src/ratpoison.h1
-rw-r--r--src/screen.c118
-rw-r--r--src/screen.h36
-rw-r--r--src/split.c264
-rw-r--r--src/window.c18
-rw-r--r--src/window.h2
13 files changed, 491 insertions, 148 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 798564b..5a10925 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,7 +17,7 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
-## $Id: Makefile.am,v 1.13 2003/03/07 11:43:26 sabetts Exp $
+## $Id: Makefile.am,v 1.14 2003/03/31 07:06:23 sabetts Exp $
bin_PROGRAMS = ratpoison
@@ -47,6 +47,8 @@ ratpoison_SOURCES = actions.c \
ratpoison.h \
sbuf.c \
sbuf.h \
+ screen.h \
+ screen.c \
split.c \
split.h \
window.c \
diff --git a/src/actions.c b/src/actions.c
index 8e18bf2..661e8f2 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -674,9 +674,9 @@ cmd_prev_frame (int interactive, void *data)
{
rp_window_frame *frame;
- frame = find_frame_prev (current_screen()->rp_current_frame);
+ frame = find_frame_prev (screen_get_frame (current_screen(), current_screen()->current_frame));
if (!frame)
- message (MESSAGE_NO_OTHER_WINDOW);
+ message (MESSAGE_NO_OTHER_FRAME);
else
set_active_frame (frame);
@@ -716,7 +716,7 @@ cmd_next_frame (int interactive, void *data)
{
rp_window_frame *frame;
- frame = find_frame_next (current_screen()->rp_current_frame);
+ frame = find_frame_next (screen_get_frame (current_screen(), current_screen()->current_frame));
if (!frame)
message (MESSAGE_NO_OTHER_FRAME);
else
@@ -778,7 +778,7 @@ cmd_select (int interactive, void *data)
{
if (strlen (str) == 1 && str[0] == '-')
{
- blank_frame (current_screen()->rp_current_frame);
+ blank_frame (screen_get_frame (current_screen(), current_screen()->current_frame));
}
/* else if ((w = find_window_name (str))) */
/* { */
@@ -1333,17 +1333,19 @@ read_split (const char *str, int max)
char *
cmd_h_split (int interactive, void *data)
{
+ rp_window_frame *frame;
int pixels;
+ frame = screen_get_frame (current_screen(), current_screen()->current_frame);
+
/* Default to dividing the frame in half. */
if (data == NULL)
- pixels = current_screen()->rp_current_frame->height / 2;
+ pixels = frame->height / 2;
else
- pixels = read_split (data, current_screen()->rp_current_frame->height);
-
+ pixels = read_split (data, frame->height);
if (pixels > 0)
- h_split_frame (current_screen()->rp_current_frame, pixels);
+ h_split_frame (frame, pixels);
else
message (" hsplit: invalid argument ");
@@ -1353,16 +1355,19 @@ cmd_h_split (int interactive, void *data)
char *
cmd_v_split (int interactive, void *data)
{
+ rp_window_frame *frame;
int pixels;
+ frame = screen_get_frame (current_screen(), current_screen()->current_frame);
+
/* Default to dividing the frame in half. */
if (data == NULL)
- pixels = current_screen()->rp_current_frame->width / 2;
+ pixels = frame->width / 2;
else
- pixels = read_split (data, current_screen()->rp_current_frame->width);
+ pixels = read_split (data, frame->width);
if (pixels > 0)
- v_split_frame (current_screen()->rp_current_frame, pixels);
+ v_split_frame (frame, pixels);
else
message (" vsplit: invalid argument ");
@@ -1390,11 +1395,11 @@ cmd_remove (int interactive, void *data)
return NULL;
}
- frame = find_frame_next (s->rp_current_frame);
+ frame = find_frame_next (screen_get_frame (s, s->current_frame));
if (frame)
{
- remove_frame (current_screen()->rp_current_frame);
+ remove_frame (screen_get_frame (s, s->current_frame));
set_active_frame (frame);
}
@@ -1406,7 +1411,7 @@ cmd_shrink (int interactive, void *data)
{
screen_info *s = current_screen ();
- resize_shrink_to_window (s->rp_current_frame);
+ resize_shrink_to_window (screen_get_frame (s, s->current_frame));
return NULL;
}
@@ -1424,6 +1429,7 @@ cmd_resize (int interactive, void *data)
unsigned int mod;
KeySym c;
Window fwin;
+ struct list_head *bk;
/* If we haven't got at least 2 frames, there isn't anything to
scale. */
@@ -1432,26 +1438,46 @@ cmd_resize (int interactive, void *data)
XGetInputFocus (dpy, &fwin, &revert);
XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime);
+ /* Save the frameset in case the user aborts. */
+ bk = screen_copy_frameset (s);
+
while (1)
{
show_frame_message (" Resize frame ");
nbytes = read_key (&c, &mod, buffer, sizeof (buffer), 1);
if (c == RESIZE_VGROW_KEY && mod == RESIZE_VGROW_MODIFIER)
- resize_frame_vertically (s->rp_current_frame, defaults.frame_resize_unit);
+ resize_frame_vertically (screen_get_frame (s, s->current_frame), defaults.frame_resize_unit);
else if (c == RESIZE_VSHRINK_KEY && mod == RESIZE_VSHRINK_MODIFIER)
- resize_frame_vertically (s->rp_current_frame, -defaults.frame_resize_unit);
+ resize_frame_vertically (screen_get_frame (s, s->current_frame), -defaults.frame_resize_unit);
else if (c == RESIZE_HGROW_KEY && mod == RESIZE_HGROW_MODIFIER)
- resize_frame_horizontally (s->rp_current_frame, defaults.frame_resize_unit);
+ resize_frame_horizontally (screen_get_frame (s, s->current_frame), defaults.frame_resize_unit);
else if (c == RESIZE_HSHRINK_KEY && mod == RESIZE_HSHRINK_MODIFIER)
- resize_frame_horizontally (s->rp_current_frame, -defaults.frame_resize_unit);
+ resize_frame_horizontally (screen_get_frame (s, s->current_frame), -defaults.frame_resize_unit);
else if (c == RESIZE_SHRINK_TO_WINDOW_KEY
&& mod == RESIZE_SHRINK_TO_WINDOW_MODIFIER)
- resize_shrink_to_window (s->rp_current_frame);
+ resize_shrink_to_window (screen_get_frame (s, s->current_frame));
+ else if (c == INPUT_ABORT_KEY && mod == INPUT_ABORT_MODIFIER)
+ {
+ rp_window_frame *cur;
+
+ screen_restore_frameset (s, bk);
+ list_for_each_entry (cur, &s->rp_window_frames, node)
+ {
+ maximize_all_windows_in_frame (cur);
+ }
+ break;
+ }
else if (c == RESIZE_END_KEY && mod == RESIZE_END_MODIFIER)
- break;
+ {
+ frameset_free (bk);
+ break;
+ }
}
+ /* It is our responsibility to free this. */
+ free (bk);
+
hide_frame_indicator ();
XSetInputFocus (dpy, fwin, RevertToPointerRoot, CurrentTime);
}
@@ -1465,8 +1491,8 @@ cmd_resize (int interactive, void *data)
return NULL;
}
- resize_frame_horizontally (s->rp_current_frame, xdelta);
- resize_frame_vertically (s->rp_current_frame, ydelta);
+ resize_frame_horizontally (screen_get_frame (s, s->current_frame), xdelta);
+ resize_frame_vertically (screen_get_frame (s, s->current_frame), ydelta);
}
return NULL;
@@ -2104,7 +2130,7 @@ cmd_defborder (int interactive, void *data)
/* Update all the visible windows. */
list_for_each_entry (win,&rp_mapped_window,node)
{
- if (win->frame)
+ if (win_get_frame (win))
maximize (win);
}
@@ -2462,7 +2488,7 @@ cmd_focusup (int interactive, void *data)
{
rp_window_frame *frame;
- if ((frame = find_frame_up (current_screen()->rp_current_frame)))
+ if ((frame = find_frame_up (screen_get_frame (current_screen(), current_screen()->current_frame))))
set_active_frame (frame);
return NULL;
@@ -2473,7 +2499,7 @@ cmd_focusdown (int interactive, void *data)
{
rp_window_frame *frame;
- if ((frame = find_frame_down (current_screen()->rp_current_frame)))
+ if ((frame = find_frame_down (screen_get_frame (current_screen(), current_screen()->current_frame))))
set_active_frame (frame);
return NULL;
@@ -2484,7 +2510,7 @@ cmd_focusleft (int interactive, void *data)
{
rp_window_frame *frame;
- if ((frame = find_frame_left (current_screen()->rp_current_frame)))
+ if ((frame = find_frame_left (screen_get_frame (current_screen(), current_screen()->current_frame))))
set_active_frame (frame);
return NULL;
@@ -2495,7 +2521,7 @@ cmd_focusright (int interactive, void *data)
{
rp_window_frame *frame;
- if ((frame = find_frame_right (current_screen()->rp_current_frame)))
+ if ((frame = find_frame_right (screen_get_frame (current_screen(), current_screen()->current_frame))))
set_active_frame (frame);
return NULL;
@@ -2707,7 +2733,7 @@ cmd_nextscreen (int interactive, void *data)
if (new_screen >= num_screens)
new_screen = 0;
- set_active_frame (screens[new_screen].rp_current_frame);
+ set_active_frame (screen_get_frame (&screens[new_screen], screens[new_screen].current_frame));
return NULL;
}
@@ -2728,7 +2754,7 @@ cmd_prevscreen (int interactive, void *data)
if (new_screen < 0)
new_screen = num_screens - 1;
- set_active_frame (screens[new_screen].rp_current_frame);
+ set_active_frame (screen_get_frame (&screens[new_screen], screens[new_screen].current_frame));
return NULL;
}
@@ -2797,7 +2823,7 @@ cmd_tmpwm (int interactive, void *data)
/* Remove the window from the frame. */
frame = find_windows_frame (win);
if (frame) cleanup_frame (frame);
- if (frame == win->scr->rp_current_frame) set_active_frame (frame);
+ if (frame->number == win->scr->current_frame) set_active_frame (frame);
/* put the window in the unmapped list. */
numset_release (rp_window_numset, win->number);
@@ -2949,3 +2975,9 @@ cmd_fselect (int interactive, void *data)
return NULL;
}
+
+char *
+cmd_restore (int interactively, void *data)
+{
+ return NULL;
+}
diff --git a/src/data.h b/src/data.h
index e87d63e..c7bba0f 100644
--- a/src/data.h
+++ b/src/data.h
@@ -32,6 +32,11 @@
#define FONT_HEIGHT(f) ((f)->max_bounds.ascent + (f)->max_bounds.descent)
#define WIN_EVENTS (StructureNotifyMask | PropertyChangeMask | ColormapChangeMask | FocusChangeMask)
+/* EMPTY is used when a frame doesn't contain a window, or a window
+ doesn't have a frame. Any time a field refers to the number of a
+ window/frame/screen/etc, Use EMPTY to denote a lack there of. */
+#define EMPTY -1
+
typedef struct rp_window rp_window;
typedef struct screen_info screen_info;
@@ -42,7 +47,9 @@ struct rp_window_frame
{
int number;
int x, y, width, height;
- rp_window *win;
+
+ /* The number of the window that is focused in this frame. */
+ int win_number;
/* For determining the last frame. */
int last_access;
@@ -88,7 +95,7 @@ struct rp_window
/* A window can be visible inside a frame but not the frame's
current window. This keeps track of what frame the window was
mapped into. */
- rp_window_frame *frame;
+ int frame_number;
struct list_head node;
};
@@ -113,9 +120,9 @@ struct screen_info
/* Keep track of which numbers have been given to frames. */
struct numset *frames_numset;
- /* Pointer to the currently focused frame. One for each screen so
+ /* The number of the currently focused frame. One for each screen so
when you switch screens the focus doesn't get frobbed. */
- rp_window_frame *rp_current_frame;
+ int current_frame;
};
struct rp_action
diff --git a/src/events.c b/src/events.c
index b656f16..e73661f 100644
--- a/src/events.c
+++ b/src/events.c
@@ -94,7 +94,7 @@ unmap_notify (XEvent *ev)
window. */
frame = find_windows_frame (win);
if (frame) cleanup_frame (frame);
- if (frame == win->scr->rp_current_frame) set_active_frame (frame);
+ if (frame->number == win->scr->current_frame) set_active_frame (frame);
withdraw_window (win);
break;
@@ -180,8 +180,12 @@ destroy_window (XDestroyWindowEvent *ev)
have been cleaned up with an unmap notify event, but just in
case... */
frame = find_windows_frame (win);
- if (frame) cleanup_frame (frame);
- if (frame == win->scr->rp_current_frame) set_active_frame (frame);
+ if (frame)
+ {
+ cleanup_frame (frame);
+ if (frame->number == win->scr->current_frame)
+ set_active_frame (frame);
+ }
unmanage (win);
@@ -319,7 +323,7 @@ client_msg (XClientMessageEvent *ev)
if (w)
set_active_window (w);
else
- blank_frame (win->scr->rp_current_frame);
+ blank_frame (screen_get_frame (win->scr, win->scr->current_frame));
}
}
else
diff --git a/src/frame.c b/src/frame.c
index 6faf26e..6ac0277 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -124,3 +124,44 @@ frame_free (screen_info *s, rp_window_frame *f)
numset_release (s->frames_numset, f->number);
free (f);
}
+
+
+rp_window_frame *
+frame_copy (rp_window_frame *frame)
+{
+ rp_window_frame *copy;
+
+ copy = xmalloc (sizeof (rp_window_frame));
+
+ copy->number = frame->number;
+ copy->x = frame->x;
+ copy->y = frame->y;
+ copy->width = frame->width;
+ copy->height = frame->height;
+ copy->win_number = frame->win_number;
+ copy->last_access = frame->last_access;
+
+ return copy;
+}
+
+char *
+frame_dump (rp_window_frame *frame)
+{
+ char *tmp;
+ struct sbuf *s;
+
+ s = sbuf_new (0);
+ sbuf_printf (s, "%d %d %d %d %d %d %d",
+ frame->number,
+ frame->x,
+ frame->y,
+ frame->width,
+ frame->height,
+ frame->win_number,
+ frame->last_access);
+
+ /* Extract the string and return it, and don't forget to free s. */
+ tmp = sbuf_get (s);
+ free (s);
+ return tmp;
+}
diff --git a/src/frame.h b/src/frame.h
index f2e1e4b..256bea3 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -38,5 +38,7 @@ int frame_left (rp_window_frame *frame);
rp_window_frame *frame_new (screen_info *s);
void frame_free (screen_info *s, rp_window_frame *f);
+rp_window_frame *frame_copy (rp_window_frame *frame);
+char *frame_dump (rp_window_frame *frame);
#endif
diff --git a/src/manage.c b/src/manage.c
index 7a19934..93fe869 100644
--- a/src/manage.c
+++ b/src/manage.c
@@ -397,26 +397,30 @@ get_state (rp_window *win)
static void
move_window (rp_window *win)
{
- if (win->frame == NULL)
+ rp_window_frame *frame;
+
+ if (win->frame_number == EMPTY)
return;
+ frame = win_get_frame (win);
+
/* X coord. */
switch (win->gravity)
{
case NorthWestGravity:
case WestGravity:
case SouthWestGravity:
- win->x = win->frame->x;
+ win->x = frame->x;
break;
case NorthGravity:
case CenterGravity:
case SouthGravity:
- win->x = win->frame->x + (win->frame->width - win->border * 2) / 2 - win->width / 2;
+ win->x = frame->x + (frame->width - win->border * 2) / 2 - win->width / 2;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
- win->x = win->frame->x + win->frame->width - win->width - win->border;
+ win->x = frame->x + frame->width - win->width - win->border;
break;
}
@@ -426,17 +430,17 @@ move_window (rp_window *win)
case NorthEastGravity:
case NorthGravity:
case NorthWestGravity:
- win->y = win->frame->y;
+ win->y = frame->y;
break;
case EastGravity:
case CenterGravity:
case WestGravity:
- win->y = win->frame->y + (win->frame->height - win->border * 2) / 2 - win->height / 2;
+ win->y = frame->y + (frame->height - win->border * 2) / 2 - win->height / 2;
break;
case SouthEastGravity:
case SouthGravity:
case SouthWestGravity:
- win->y = win->frame->y + win->frame->height - win->height - win->border;
+ win->y = frame->y + frame->height - win->height - win->border;
break;
}
}
@@ -449,15 +453,15 @@ maximize_transient (rp_window *win)
rp_window_frame *frame;
int maxx, maxy;
+ frame = win_get_frame (win);
+
/* We can't maximize a window if it has no frame. */
- if (win->frame == NULL)
+ if (frame == NULL)
return;
/* Set the window's border */
win->border = defaults.window_border_width;
- frame = win->frame;
-
/* Always use the window's current width and height for
transients. */
maxx = win->width;
@@ -507,15 +511,15 @@ maximize_normal (rp_window *win)
rp_window_frame *frame;
int maxx, maxy;
+ frame = win_get_frame (win);
+
/* We can't maximize a window if it has no frame. */
- if (win->frame == NULL)
+ if (frame == NULL)
return;
/* Set the window's border */
win->border = defaults.window_border_width;
- frame = win->frame;
-
/* Honour the window's maximum size */
if (win->hints->flags & PMaxSize)
{
@@ -670,7 +674,7 @@ hide_window (rp_window *win)
if (win == NULL) return;
/* An unmapped window is not inside a frame. */
- win->frame = NULL;
+ win->frame_number = EMPTY;
/* Ignore the unmap_notify event. */
XSelectInput(dpy, win->w, WIN_EVENTS&~(StructureNotifyMask));
@@ -748,7 +752,7 @@ hide_others (rp_window *win)
{
if (find_windows_frame (cur)
|| cur->state != NormalState
- || cur->frame != frame)
+ || cur->frame_number != frame->number)
continue;
hide_window (cur);
diff --git a/src/ratpoison.h b/src/ratpoison.h
index 4a5dde7..cc1420f 100644
--- a/src/ratpoison.h
+++ b/src/ratpoison.h
@@ -69,6 +69,7 @@ extern XGCValues gv;
#include "sbuf.h"
#include "split.h"
#include "frame.h"
+#include "screen.h"
void clean_up ();
screen_info *find_screen (Window w);
diff --git a/src/screen.c b/src/screen.c
new file mode 100644
index 0000000..aa7b1df
--- /dev/null
+++ b/src/screen.c
@@ -0,0 +1,118 @@
+/* Copyright (C) 2000-2003 Shawn Betts
+ *
+ * This file is part of ratpoison.
+ *
+ * ratpoison is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ratpoison is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ */
+
+#include "ratpoison.h"
+
+int
+screen_width (screen_info *s)
+{
+ return DisplayWidth (dpy, s->screen_num) - defaults.padding_right - defaults.padding_left;
+}
+
+int
+screen_height (screen_info *s)
+{
+ return DisplayHeight (dpy, s->screen_num) - defaults.padding_bottom - defaults.padding_top;
+}
+
+int
+screen_left (screen_info *s)
+{
+ return defaults.padding_left;
+}
+
+int
+screen_right (screen_info *s)
+{
+ return screen_left (s) + screen_width (s);
+}
+
+int
+screen_top (screen_info *s)
+{
+ return defaults.padding_top;
+}
+
+int
+screen_bottom (screen_info *s)
+{
+ return screen_top (s) + screen_height (s);
+}
+
+/* Returns a pointer to a list of frames. */
+struct list_head *
+screen_copy_frameset (screen_info *s)
+{
+ struct list_head *head;
+ rp_window_frame *cur;
+
+ /* Init our new list. */
+ head = xmalloc (sizeof (struct list_head));
+ INIT_LIST_HEAD (head);
+
+ /* Copy each frame to our new list. */
+ list_for_each_entry (cur, &s->rp_window_frames, node)
+ {
+ list_add_tail (&(frame_copy (cur))->node, head);
+ }
+
+ return head;
+}
+
+/* Set head as the frameset, deleting the existing one. */
+void
+screen_restore_frameset (screen_info *s, struct list_head *head)
+{
+ frameset_free (&s->rp_window_frames);
+ INIT_LIST_HEAD (&s->rp_window_frames);
+
+ /* Hook in our new frameset. */
+ list_splice (head, &s->rp_window_frames);
+}
+
+/* Given a list of frames, free them, but don't remove their numbers
+ from the numset. */
+void
+frameset_free (struct list_head *head)
+{
+ rp_window_frame *frame;
+ struct list_head *iter, *tmp;
+
+ list_for_each_safe_entry (frame, iter, tmp, head, node)
+ {
+ /* FIXME: what if rp_window_frames has memory inside its struct
+ that needs to be freed? */
+ free (frame);
+ }
+}
+
+rp_window_frame *
+screen_get_frame (screen_info *s, int frame_num)
+{
+ rp_window_frame *cur;
+
+ list_for_each_entry (cur, &s->rp_window_frames, node)
+ {
+ if (cur->number == frame_num)
+ return cur;
+ }
+
+ return NULL;
+}
diff --git a/src/screen.h b/src/screen.h
new file mode 100644
index 0000000..5b0bbc2
--- /dev/null
+++ b/src/screen.h
@@ -0,0 +1,36 @@
+/* Copyright (C) 2000-2003 Shawn Betts
+ *
+ * This file is part of ratpoison.
+ *
+ * ratpoison is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ratpoison is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
+ */
+
+#ifndef SCREEN_H
+#define SCREEN_H
+
+int screen_bottom (screen_info *s);
+int screen_top (screen_info *s);
+int screen_right (screen_info *s);
+int screen_left (screen_info *s);
+int screen_height (screen_info *s);
+int screen_width (screen_info *s);
+
+struct list_head *screen_copy_frameset (screen_info *s);
+void screen_restore_frameset (screen_info *s, struct list_head *head);
+void frameset_free (struct list_head *head);
+rp_window_frame *screen_get_frame (screen_info *s, int frame_num);
+
+#endif
diff --git a/src/split.c b/src/split.c
index b0d6ff1..7db350a 100644
--- a/src/split.c
+++ b/src/split.c
@@ -85,14 +85,20 @@ cleanup_frame (rp_window_frame *frame)
rp_window *
set_frames_window (rp_window_frame *frame, rp_window *win)
{
- rp_window *last_win;
+ int last_win;
- last_win = frame->win;
- frame->win = win;
+ last_win = frame->win_number;
if (win)
- win->frame = frame;
+ {
+ frame->win_number = win->number;
+ win->frame_number = frame->number;
+ }
+ else
+ {
+ frame->win_number = EMPTY;
+ }
- return last_win;
+ return find_window_number (last_win);
}
static screen_info *
@@ -120,7 +126,7 @@ maximize_all_windows_in_frame (rp_window_frame *frame)
list_for_each_entry (win, &rp_mapped_window, node)
{
- if (win->frame == frame)
+ if (win->frame_number == frame->number)
{
maximize (win);
}
@@ -136,22 +142,24 @@ maximize_frame (rp_window_frame *frame)
frame->x = defaults.padding_left;
frame->y = defaults.padding_top;
- frame->width = DisplayWidth (dpy, s->screen_num) - defaults.padding_right - defaults.padding_left;
- frame->height = DisplayHeight (dpy, s->screen_num) - defaults.padding_bottom - defaults.padding_top;
+ frame->width = screen_width (s);
+ frame->height = screen_height (s);
}
/* Create a full screen frame */
static void
create_initial_frame (screen_info *screen)
{
- screen->rp_current_frame = frame_new (screen);
+ rp_window_frame *frame;
- list_add_tail (&screen->rp_current_frame->node, &screen->rp_window_frames);
+ frame = frame_new (screen);
+ screen->current_frame = frame->number;
+ list_add_tail (&frame->node, &screen->rp_window_frames);
- update_last_access (screen->rp_current_frame);
+ update_last_access (frame);
- maximize_frame (screen->rp_current_frame);
- set_frames_window (screen->rp_current_frame, NULL);
+ maximize_frame (frame);
+ set_frames_window (frame, NULL);
}
void
@@ -179,7 +187,7 @@ find_last_frame (screen_info *s)
list_for_each_entry (cur, &s->rp_window_frames, node)
{
- if (cur != s->rp_current_frame
+ if (cur->number != s->current_frame
&& cur->last_access > last_access)
{
last_access = cur->last_access;
@@ -201,7 +209,7 @@ find_windows_frame (rp_window *win)
list_for_each_entry (cur, &s->rp_window_frames, node)
{
- if (cur->win == win) return cur;
+ if (cur->win_number == win->number) return cur;
}
return NULL;
@@ -224,7 +232,8 @@ find_frame_prev (rp_window_frame *frame)
rp_window *
current_window ()
{
- return screens[rp_current_screen].rp_current_frame->win;
+ return find_window_number (screen_get_frame (&screens[rp_current_screen],
+ screens[rp_current_screen].current_frame)->win_number);
}
static int
@@ -262,7 +271,7 @@ find_window_for_frame (rp_window_frame *frame)
&& !find_windows_frame (cur)
&& cur->last_access >= last_access
&& window_fits_in_frame (cur, frame)
- && !cur->frame)
+ && cur->frame_number == EMPTY)
{
most_recent = cur;
last_access = cur->last_access;
@@ -286,14 +295,8 @@ split_frame (rp_window_frame *frame, int way, int pixels)
/* Make our new frame. */
new_frame = frame_new (s);
- /* It seems intuitive to make the last frame the newly created
- frame. */
- update_last_access (new_frame);
-
- /* TODO: don't put the new frame at the end of the list, put it
- after the existing frame. Then cycling frames cycles in the order
- they were created. */
- list_add (&new_frame->node, &s->rp_current_frame->node);
+ /* Add the frame to the frameset. */
+ list_add (&new_frame->node, &(screen_get_frame (s, s->current_frame)->node));
set_frames_window (new_frame, NULL);
@@ -335,10 +338,10 @@ split_frame (rp_window_frame *frame, int way, int pixels)
}
/* resize the existing frame */
- if (frame->win)
+ if (frame->win_number != EMPTY)
{
maximize_all_windows_in_frame (frame);
- XRaiseWindow (dpy, frame->win->w);
+ XRaiseWindow (dpy, find_window_number (frame->win_number)->w);
}
show_frame_indicator();
@@ -371,14 +374,14 @@ remove_all_splits ()
/* Hide all the windows not in the current frame. */
list_for_each_entry (win, &rp_mapped_window, node)
{
- if (win->frame != s->rp_current_frame)
+ if (win->frame_number != s->current_frame)
hide_window (win);
}
/* Delete all the frames except the current one. */
list_for_each_safe_entry (frame, iter, tmp, &s->rp_window_frames, node)
{
- if (frame != s->rp_current_frame)
+ if (frame->number != s->current_frame)
{
list_del (&frame->node);
frame_free (s, frame);
@@ -386,30 +389,35 @@ remove_all_splits ()
}
/* Maximize the frame and the windows in the frame. */
- maximize_frame (s->rp_current_frame);
- maximize_all_windows_in_frame (s->rp_current_frame);
+ maximize_frame (screen_get_frame (s, s->current_frame));
+ maximize_all_windows_in_frame (screen_get_frame (s, s->current_frame));
}
/* Shrink the size of the frame to fit it's current window. */
void
resize_shrink_to_window (rp_window_frame *frame)
{
- if (frame->win == NULL) return;
+ rp_window *win;
+
+ if (frame->win_number == EMPTY) return;
- resize_frame_horizontally (frame, frame->win->width + frame->win->border*2 - frame->width);
- resize_frame_vertically (frame, frame->win->height + frame->win->border*2 - frame->height);
+ win = find_window_number (frame->win_number);
+
+ resize_frame_horizontally (frame, win->width + win->border*2 - frame->width);
+ resize_frame_vertically (frame, win->height + win->border*2 - frame->height);
}
/* resize_frame is a generic frame resizer that can resize vertically,
horizontally, to the right, to the left, etc. It all depends on the
- functions passed to it. */
-static void
+ functions passed to it. Returns -1 if the resize failed, 0 for
+ success. */
+static int
resize_frame (rp_window_frame *frame, rp_window_frame *pusher, int diff,
int (*c1)(rp_window_frame *), int (c2)(rp_window_frame *),
int (*c3)(rp_window_frame *), int (c4)(rp_window_frame *),
void (*resize1)(rp_window_frame *, int),
void (*resize2)(rp_window_frame *, int),
- void (*resize3)(rp_window_frame *, rp_window_frame *, int))
+ int (*resize3)(rp_window_frame *, rp_window_frame *, int))
{
screen_info *s = frames_screen (frame);
rp_window_frame *cur;
@@ -423,6 +431,10 @@ resize_frame (rp_window_frame *frame, rp_window_frame *pusher, int diff,
moved then this frame is affected by the resize. */
if ((*c1)(cur) == (*c3)(frame))
{
+ /* If the frame can't get any smaller, then fail. */
+ if (diff > 0
+ && abs ((*c3)(cur) - (*c1)(cur)) - diff <= defaults.window_border_width * 2)
+ return -1;
/* Test for this circumstance:
--+
| |+-+
@@ -451,7 +463,9 @@ resize_frame (rp_window_frame *frame, rp_window_frame *pusher, int diff,
|| ((*c4)(cur) > (*c2)(frame)
&& (*c4)(cur) <= (*c4)(frame)))
{
- resize3 (cur, frame, -diff);
+ /* Attempt to resize cur. */
+ if (resize3 (cur, frame, -diff) == -1)
+ return -1;
}
}
}
@@ -459,47 +473,49 @@ resize_frame (rp_window_frame *frame, rp_window_frame *pusher, int diff,
/* Finally, resize the frame and the windows inside. */
(*resize1) (frame, diff);
maximize_all_windows_in_frame (frame);
+
+ return 0;
}
-static void resize_frame_bottom (rp_window_frame *frame, rp_window_frame *pusher, int diff);
-static void resize_frame_top (rp_window_frame *frame, rp_window_frame *pusher, int diff);
-static void resize_frame_left (rp_window_frame *frame, rp_window_frame *pusher, int diff);
-static void resize_frame_right (rp_window_frame *frame, rp_window_frame *pusher, int diff);
+static int resize_frame_bottom (rp_window_frame *frame, rp_window_frame *pusher, int diff);
+static int resize_frame_top (rp_window_frame *frame, rp_window_frame *pusher, int diff);
+static int resize_frame_left (rp_window_frame *frame, rp_window_frame *pusher, int diff);
+static int resize_frame_right (rp_window_frame *frame, rp_window_frame *pusher, int diff);
/* Resize frame by moving it's right side. */
-static void
+static int
resize_frame_right (rp_window_frame *frame, rp_window_frame *pusher, int diff)
{
- resize_frame (frame, pusher, diff,
- frame_left, frame_top, frame_right, frame_bottom,
- frame_resize_right, frame_resize_left, resize_frame_left);
+ return resize_frame (frame, pusher, diff,
+ frame_left, frame_top, frame_right, frame_bottom,
+ frame_resize_right, frame_resize_left, resize_frame_left);
}
/* Resize frame by moving it's left side. */
-static void
+static int
resize_frame_left (rp_window_frame *frame, rp_window_frame *pusher, int diff)
{
- resize_frame (frame, pusher, diff,
- frame_right, frame_top, frame_left, frame_bottom,
- frame_resize_left, frame_resize_right, resize_frame_right);
+ return resize_frame (frame, pusher, diff,
+ frame_right, frame_top, frame_left, frame_bottom,
+ frame_resize_left, frame_resize_right, resize_frame_right);
}
/* Resize frame by moving it's top side. */
-static void
+static int
resize_frame_top (rp_window_frame *frame, rp_window_frame *pusher, int diff)
{
- resize_frame (frame, pusher, diff,
- frame_bottom, frame_left, frame_top, frame_right,
- frame_resize_up, frame_resize_down, resize_frame_bottom);
+ return resize_frame (frame, pusher, diff,
+ frame_bottom, frame_left, frame_top, frame_right,
+ frame_resize_up, frame_resize_down, resize_frame_bottom);
}
/* Resize frame by moving it's bottom side. */
-static void
+static int
resize_frame_bottom (rp_window_frame *frame, rp_window_frame *pusher, int diff)
{
- resize_frame (frame, pusher, diff,
- frame_top, frame_left, frame_bottom, frame_right,
- frame_resize_down, frame_resize_up, resize_frame_top);
+ return resize_frame (frame, pusher, diff,
+ frame_top, frame_left, frame_bottom, frame_right,
+ frame_resize_down, frame_resize_up, resize_frame_top);
}
/* Resize frame diff pixels by expanding it to the right. If the frame
@@ -507,19 +523,45 @@ resize_frame_bottom (rp_window_frame *frame, rp_window_frame *pusher, int diff)
void
resize_frame_horizontally (rp_window_frame *frame, int diff)
{
+ int (*resize_fn)(rp_window_frame *, rp_window_frame*, int);
+ struct list_head *l;
screen_info *s = frames_screen (frame);
if (num_frames (s) < 2 || diff == 0)
return;
- if (frame_right (frame) < DisplayWidth (dpy, s->screen_num) - defaults.padding_right - defaults.padding_left)
+ if (frame_width (frame) + diff <= defaults.window_border_width * 2)
+ return;
+
+ /* Find out which resize function to use. */
+ if (frame_right (frame) < screen_right (s))
+ {
+ resize_fn = resize_frame_right;
+ }
+ else if (frame_left (frame) > screen_left (s))
+ {
+ resize_fn = resize_frame_left;
+ }
+ else
+ {
+ return;
+ }
+
+ /* Copy the frameset. If the resize fails, then we restore the
+ original one. */
+ l = screen_copy_frameset (s);
+
+ if ((*resize_fn) (frame, NULL, diff) == -1)
{
- resize_frame_right (frame, NULL, diff);
+ screen_restore_frameset (s, l);
}
- else if (frame_left (frame) > defaults.padding_left)
+ else
{
- resize_frame_left (frame, NULL, diff);
+ frameset_free (l);
}
+
+ /* It's our responsibility to free this. */
+ free (l);
}
/* Resize frame diff pixels by expanding it down. If the frame is
@@ -527,19 +569,45 @@ resize_frame_horizontally (rp_window_frame *frame, int diff)
void
resize_frame_vertically (rp_window_frame *frame, int diff)
{
+ int (*resize_fn)(rp_window_frame *, rp_window_frame*, int);
+ struct list_head *l;
screen_info *s = frames_screen (frame);
if (num_frames (s) < 2 || diff == 0)
return;
- if (frame_bottom (frame) < DisplayHeight (dpy, s->screen_num) - defaults.padding_bottom - defaults.padding_top)
+ if (frame_height (frame) + diff <= defaults.window_border_width * 2)
+ return;
+
+ /* Find out which resize function to use. */
+ if (frame_bottom (frame) < screen_bottom (s))
+ {
+ resize_fn = resize_frame_bottom;
+ }
+ else if (frame_top (frame) > screen_top (s))
+ {
+ resize_fn = resize_frame_top;
+ }
+ else
+ {
+ return;
+ }
+
+ /* Copy the frameset. If the resize fails, then we restore the
+ original one. */
+ l = screen_copy_frameset (s);
+
+ if ((*resize_fn) (frame, NULL, diff) == -1)
{
- resize_frame_bottom (frame, NULL, diff);
+ screen_restore_frameset (s, l);
}
- else if (frame_top (frame) > defaults.padding_top)
+ else
{
- resize_frame_top (frame, NULL, diff);
+ frameset_free (l);
}
+
+ /* It's our responsibility to free this. */
+ free (l);
}
static int
@@ -623,6 +691,7 @@ remove_frame (rp_window_frame *frame)
screen_info *s;
int area;
rp_window_frame *cur;
+ rp_window *win;
if (frame == NULL) return;
@@ -632,22 +701,23 @@ remove_frame (rp_window_frame *frame)
PRINT_DEBUG (("Total Area: %d\n", area));
list_del (&frame->node);
- hide_window (frame->win);
- hide_others (frame->win);
+ win = find_window_number (frame->win_number);
+ hide_window (win);
+ hide_others (win);
list_for_each_entry (cur, &s->rp_window_frames, node)
{
rp_window_frame tmp_frame;
int fits = 0;
- if (cur->win)
- {
- PRINT_DEBUG (("Trying frame containing window '%s'\n", window_name (cur->win)));
- }
- else
- {
- PRINT_DEBUG (("Trying some empty frame\n"));
- }
+/* if (cur->win_number != EMPTY) */
+/* { */
+/* PRINT_DEBUG (("Trying frame containing window '%s'\n", window_name (cur->win))); */
+/* } */
+/* else */
+/* { */
+/* PRINT_DEBUG (("Trying some empty frame\n")); */
+/* } */
/* Backup the frame */
memcpy (&tmp_frame, cur, sizeof (rp_window_frame));
@@ -716,10 +786,11 @@ remove_frame (rp_window_frame *frame)
/* 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)
+ if (cur->win_number != EMPTY)
{
+ win = find_window_number (cur->win_number);
maximize_all_windows_in_frame (cur);
- XRaiseWindow (dpy, cur->win->w);
+ XRaiseWindow (dpy, win->w);
}
}
else
@@ -738,18 +809,23 @@ set_active_frame (rp_window_frame *frame)
{
screen_info *old_s = current_screen();
screen_info *s = frames_screen (frame);
- rp_window_frame *old = current_screen()->rp_current_frame;
+ int old = current_screen()->current_frame;
+ rp_window *win, *old_win;
+
+ win = find_window_number (frame->win_number);
+ old_win = find_window_number (screen_get_frame (current_screen(),
+ current_screen()->current_frame)->win_number);
/* Make the switch */
- give_window_focus (frame->win, old->win);
+ give_window_focus (win, old_win);
update_last_access (frame);
- s->rp_current_frame = frame;
+ s->current_frame = frame->number;
/* If frame->win == NULL, then rp_current_screen is not updated. */
rp_current_screen = s->screen_num;
/* Possibly show the frame indicator. */
- if ((old != s->rp_current_frame && num_frames(s) > 1)
+ if ((old != s->current_frame && num_frames(s) > 1)
|| s != old_s)
{
show_frame_indicator();
@@ -757,7 +833,7 @@ set_active_frame (rp_window_frame *frame)
/* If the frame has no window to give focus to, give the key window
focus. */
- if( !frame->win )
+ if(frame->win_number == EMPTY)
{
XSetInputFocus (dpy, s->key_window,
RevertToPointerRoot, CurrentTime);
@@ -767,10 +843,13 @@ set_active_frame (rp_window_frame *frame)
void
blank_frame (rp_window_frame *frame)
{
- if (frame->win == NULL) return;
+ rp_window *win;
+
+ if (frame->win_number == EMPTY) return;
- hide_window (frame->win);
- hide_others (frame->win);
+ win = find_window_number (frame->number);
+ hide_window (win);
+ hide_others (win);
set_frames_window (frame, NULL);
@@ -797,18 +876,19 @@ show_frame_message (char *msg)
{
screen_info *s = current_screen ();
int width, height;
+ rp_window_frame *frame;
+
+ frame = screen_get_frame (s, s->current_frame);
width = defaults.bar_x_padding * 2 + XTextWidth (defaults.font, msg, strlen (msg));
height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2);
- XMoveResizeWindow (dpy, current_screen()->frame_window,
- current_screen()->rp_current_frame->x
- + current_screen()->rp_current_frame->width / 2 - width / 2,
- current_screen()->rp_current_frame->y
- + current_screen()->rp_current_frame->height / 2 - height / 2,
+ XMoveResizeWindow (dpy, s->frame_window,
+ frame->x + frame->width / 2 - width / 2,
+ frame->y + frame->height / 2 - height / 2,
width, height);
- XMapRaised (dpy, current_screen()->frame_window);
+ XMapRaised (dpy, s->frame_window);
XClearWindow (dpy, s->frame_window);
XSync (dpy, False);
diff --git a/src/window.c b/src/window.c
index 87ad967..a3042ab 100644
--- a/src/window.c
+++ b/src/window.c
@@ -178,7 +178,10 @@ find_window (Window w)
void
set_current_window (rp_window *win)
{
- set_frames_window (current_screen()->rp_current_frame, win);
+ rp_window_frame *frame;
+
+ frame = screen_get_frame (current_screen(), current_screen()->current_frame);
+ set_frames_window (frame, win);
}
rp_window *
@@ -475,10 +478,12 @@ void
set_active_window (rp_window *win)
{
rp_window *last_win;
+ rp_window_frame *frame;
if (win == NULL) return;
- last_win = set_frames_window (win->scr->rp_current_frame, win);
+ frame = screen_get_frame (win->scr, win->scr->current_frame);
+ last_win = set_frames_window (frame, win);
if (last_win) PRINT_DEBUG (("last window: %s\n", window_name (last_win)));
PRINT_DEBUG (("new window: %s\n", window_name (win)));
@@ -683,3 +688,12 @@ free_window_stuff ()
{
numset_free (rp_window_numset);
}
+
+rp_window_frame *
+win_get_frame (rp_window *win)
+{
+ if (win->frame_number != EMPTY)
+ return screen_get_frame (win->scr, win->frame_number);
+ else
+ return NULL;
+}
diff --git a/src/window.h b/src/window.h
index f15c26b..1ecf16b 100644
--- a/src/window.h
+++ b/src/window.h
@@ -63,4 +63,6 @@ void get_window_list (char *fmt, char *delim, struct sbuf *buffer,
void init_window_stuff ();
void free_window_stuff ();
+rp_window_frame *win_get_frame (rp_window *win);
+
#endif /* ! _RATPOISON_LIST_H */