summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c113
-rw-r--r--src/actions.h1
-rw-r--r--src/data.h4
-rw-r--r--src/main.c5
-rw-r--r--src/split.c26
-rw-r--r--src/split.h1
6 files changed, 148 insertions, 2 deletions
diff --git a/src/actions.c b/src/actions.c
index e655341..cfce0aa 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -92,6 +92,7 @@ static user_command user_commands[] =
{"resize", cmd_resize, arg_STRING},
{"shrink", cmd_shrink, arg_VOID},
{"tmpwm", cmd_tmpwm, arg_STRING},
+ {"fselect", cmd_fselect, arg_VOID},
/*@end (tag required for genrpbindings) */
/* Commands to set default behavior. */
@@ -2825,3 +2826,115 @@ cmd_tmpwm (int interactive, void *data)
/* And we're back in ratpoison. */
return NULL;
}
+
+/* Select a frame by number. */
+char *
+cmd_fselect (int interactive, void *data)
+{
+ rp_window_frame *frame;
+ screen_info *s = current_screen();
+ int fnum = -1;
+
+ /* If the command was specified on the command line or an argument
+ was supplied to it, then try to read that argument. */
+ if (!interactive || data != NULL)
+ {
+ if (data == NULL)
+ {
+ /* The command was from the command line, but they didn't
+ specify an argument. FIXME: give some indication of
+ failure. */
+ return NULL;
+ }
+
+ /* Attempt to read the argument. */
+ if (sscanf (data, "%d", &fnum) < 1)
+ {
+ message (" fselect: numerical argument required ");
+ return NULL;
+ }
+ }
+ /* The command was called interactively and no argument was
+ supplied, so we show the frames' numbers and read a number from
+ the keyboard. */
+ else
+ {
+ KeySym c;
+ unsigned int mod;
+ Window fwin;
+ int revert;
+ Window *wins;
+ XSetWindowAttributes attr;
+ int i;
+ rp_window_frame *cur;
+
+ /* Set up the window attributes to be used in the loop. */
+ attr.border_pixel = s->fg_color;
+ attr.background_pixel = s->bg_color;
+ attr.override_redirect = True;
+
+ wins = xmalloc (sizeof (Window) * num_frames (s));
+
+ /* Loop through each frame and display its number in it's top
+ left corner. */
+ i = 0;
+ list_for_each_entry (cur, &s->rp_window_frames, node)
+ {
+ int width, height;
+ char *num;
+
+ /* Create the string to be displayed in the window and
+ determine the height and width of the window. */
+ num = xsprintf (" %d ", cur->number);
+ width = defaults.bar_x_padding * 2 + XTextWidth (defaults.font, num, strlen (num));
+ height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2);
+
+ /* Create and map the window. */
+ wins[i] = XCreateWindow (dpy, s->root, cur->x, cur->y, width, height, 1,
+ CopyFromParent, CopyFromParent, CopyFromParent,
+ CWOverrideRedirect | CWBorderPixel | CWBackPixel,
+ &attr);
+ XMapWindow (dpy, wins[i]);
+ XClearWindow (dpy, wins[i]);
+
+ /* Display the frame's number inside the window. */
+ XDrawString (dpy, wins[i], s->normal_gc,
+ defaults.bar_x_padding,
+ defaults.bar_y_padding + defaults.font->max_bounds.ascent,
+ num, strlen (num));
+
+ free (num);
+ i++;
+ }
+ XSync (dpy, False);
+
+ /* Read a key. */
+ XGetInputFocus (dpy, &fwin, &revert);
+ XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime);
+ read_key (&c, &mod, NULL, 0);
+ XSetInputFocus (dpy, fwin, RevertToPointerRoot, CurrentTime);
+
+ /* Destroy our number windows and free the array. */
+ for (i=0; i<num_frames (s); i++)
+ XDestroyWindow (dpy, wins[i]);
+
+ free (wins);
+
+ /* FIXME: big assumption here. We don't know for sure if all the
+ number keys are between XK_0 and XK_9. */
+ if (c >= XK_0 && c <= XK_9)
+ fnum = c - XK_0;
+ else
+ return NULL;
+ }
+
+ /* Now that we have a frame number to go to, let's try to jump to
+ it. */
+ frame = find_frame_number (s, fnum);
+ if (frame)
+ set_active_frame (frame);
+ else
+ marked_message_printf (0, 0, " fselect: No such frame (%d) ", fnum);
+
+ return NULL;
+}
diff --git a/src/actions.h b/src/actions.h
index 643bec5..70a23f4 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -116,6 +116,7 @@ char *cmd_nextscreen (int interactive, void *data);
char *cmd_unalias (int interactive, void *data);
char *cmd_warp(int interactive, void *data);
char *cmd_tmpwm (int interactive, void *data);
+char *cmd_fselect (int interactive, void *data);
void initialize_default_keybindings (void);
void free_keybindings ();
diff --git a/src/data.h b/src/data.h
index 2164b5a..e87d63e 100644
--- a/src/data.h
+++ b/src/data.h
@@ -23,6 +23,7 @@
#define _RATPOISON_DATA_H
#include "linkedlist.h"
+#include "number.h"
#include <X11/X.h>
#include <X11/Xlib.h>
@@ -109,6 +110,9 @@ struct screen_info
always be one in the list. */
struct list_head rp_window_frames;
+ /* 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
when you switch screens the focus doesn't get frobbed. */
rp_window_frame *rp_current_frame;
diff --git a/src/main.c b/src/main.c
index 817b231..ce854b0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -632,6 +632,9 @@ init_screen (screen_info *s, int screen_num)
| SubstructureRedirectMask | SubstructureNotifyMask );
XSync (dpy, False);
+ /* Create the numset for the frames. */
+ s->frames_numset = numset_new ();
+
/* Build the display string for each screen */
s->display_string = xmalloc (strlen(DisplayString (dpy)) + 21);
sprintf (s->display_string, "DISPLAY=%s", DisplayString (dpy));
@@ -720,6 +723,8 @@ free_screen (screen_info *s)
XFreeGC (dpy, s->normal_gc);
free (s->display_string);
+
+ numset_free (s->frames_numset);
}
void
diff --git a/src/split.c b/src/split.c
index e52fd94..c110001 100644
--- a/src/split.c
+++ b/src/split.c
@@ -148,7 +148,9 @@ create_initial_frame (screen_info *screen)
list_add_tail (&screen->rp_current_frame->node, &screen->rp_window_frames);
+ screen->rp_current_frame->number = numset_request (screen->frames_numset);
update_last_access (screen->rp_current_frame);
+
maximize_frame (screen->rp_current_frame);
set_frames_window (screen->rp_current_frame, NULL);
}
@@ -284,6 +286,9 @@ split_frame (rp_window_frame *frame, int way, int pixels)
new_frame = xmalloc (sizeof (rp_window_frame));
+ /* Give the frame a unique number. */
+ new_frame->number = numset_request (s->frames_numset);
+
/* It seems intuitive to make the last frame the newly created
frame. */
update_last_access (new_frame);
@@ -291,7 +296,7 @@ split_frame (rp_window_frame *frame, int way, int pixels)
/* 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_tail (&new_frame->node, &s->rp_window_frames);
+ list_add (&new_frame->node, &s->rp_current_frame->node);
set_frames_window (new_frame, NULL);
@@ -379,6 +384,8 @@ remove_all_splits ()
if (frame != s->rp_current_frame)
{
list_del (&frame->node);
+
+ numset_release (s->frames_numset, frame->number);
free (frame);
}
}
@@ -520,7 +527,7 @@ resize_frame_horizontally (rp_window_frame *frame, int diff)
list_for_each_entry (cur, &s->rp_window_frames, node)
{
if (cur->x == (frame->x + frame->width)
- && (cur->y + cur->height) > frame->y
+ && (cur->y + cur->height) > frame->y
&& cur->y < (frame->y + frame->height))
{
cur->width -= diff;
@@ -687,6 +694,7 @@ remove_frame (rp_window_frame *frame)
area = total_frame_area(s);
PRINT_DEBUG (("Total Area: %d\n", area));
+ numset_release (s->frames_numset, frame->number);
list_del (&frame->node);
hide_window (frame->win);
hide_others (frame->win);
@@ -940,3 +948,17 @@ find_frame_right (rp_window_frame *frame)
return NULL;
}
+
+rp_window_frame *
+find_frame_number (screen_info *s, int num)
+{
+ rp_window_frame *cur;
+
+ list_for_each_entry (cur, &s->rp_window_frames, node)
+ {
+ if (cur->number == num)
+ return cur;
+ }
+
+ return NULL;
+}
diff --git a/src/split.h b/src/split.h
index 7bf56d3..79667cc 100644
--- a/src/split.h
+++ b/src/split.h
@@ -50,5 +50,6 @@ rp_window_frame *find_frame_left (rp_window_frame *frame);
rp_window_frame *find_frame_down (rp_window_frame *frame);
rp_window_frame *find_frame_up (rp_window_frame *frame);
rp_window_frame *find_last_frame (screen_info *s);
+rp_window_frame *find_frame_number (screen_info *s, int num);
#endif