summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions.c9
-rw-r--r--src/actions.h1
-rw-r--r--src/conf.h11
-rw-r--r--src/data.h1
-rw-r--r--src/events.c29
-rw-r--r--src/main.c40
-rw-r--r--src/split.c61
-rw-r--r--src/split.h2
8 files changed, 140 insertions, 14 deletions
diff --git a/src/actions.c b/src/actions.c
index b33941e..ab486bd 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -131,6 +131,8 @@ initialize_default_keybindings (void)
add_keybinding (XK_Tab, 0, "focus");
add_keybinding (XK_Q, 0, "only");
add_keybinding (XK_R, 0, "remove");
+ add_keybinding (XK_f, 0, "curframe");
+ add_keybinding (XK_f, ControlMask, "curframe");
}
user_command user_commands[] =
@@ -161,6 +163,7 @@ user_command user_commands[] =
{"only", cmd_only, arg_VOID},
{"remove", cmd_remove, arg_VOID},
{"banish", cmd_banish, arg_VOID},
+ {"curframe", cmd_curframe, arg_VOID},
/* the following screen commands may or may not be able to be
implemented. See the screen documentation for what should be
@@ -857,3 +860,9 @@ cmd_banish (void *data)
XWarpPointer (dpy, None, s->root, 0, 0, 0, 0, s->root_attr.width - 2, s->root_attr.height - 2);
}
+
+void
+cmd_curframe (void *data)
+{
+ show_frame_indicator();
+}
diff --git a/src/actions.h b/src/actions.h
index 191b825..b479ab1 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -70,6 +70,7 @@ void cmd_v_split (void *data);
void cmd_only (void *data);
void cmd_remove (void *data);
void cmd_banish (void *data);
+void cmd_curframe (void *data);
/* void cmd_xterm (void *data); */
diff --git a/src/conf.h b/src/conf.h
index e262ee4..a855a21 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -57,6 +57,12 @@
#define BAR_LOCATION 3 /* 0=bottom-left 1=top-left 2=bottom-right 3=top-right */
#define BAR_TIMEOUT 5 /* Number of seconds before the progam bar autohides 0=don't autohide */
+/* Number of seconds before the frame indicator disappears */
+#define FRAME_INDICATOR_TIMEOUT 1
+
+/* What to display in the frame indicator */
+#define FRAME_STRING "Current Frame"
+
#define PADDING_LEFT 0 /* space not to be taken up around managed windows */
#define PADDING_TOP 0
#define PADDING_RIGHT 0
@@ -69,4 +75,9 @@
mostly for use with hand-helds. */
#define UNMANAGED_WINDOW_LIST "xapm","xclock","xscribble"
+#define RAT_WIDTH 16
+#define RAT_HEIGHT 16
+#define RAT_HOT_X 8
+#define RAT_HOT_Y 8
+
#endif /* !_ _RATPOISON_CONF_H */
diff --git a/src/data.h b/src/data.h
index 080f7ee..300059a 100644
--- a/src/data.h
+++ b/src/data.h
@@ -84,6 +84,7 @@ struct screen_info
int bar_is_raised;
int screen_num; /* Our screen number as dictated my X */
Colormap def_cmap;
+ Cursor rat;
};
struct rp_action
diff --git a/src/events.c b/src/events.c
index b0c9a1b..092e2bc 100644
--- a/src/events.c
+++ b/src/events.c
@@ -99,7 +99,10 @@ unmap_notify (XEvent *ev)
XSync(dpy, False);
- if (win == current_window()) cmd_other (NULL);
+ if (frame == rp_current_frame)
+ {
+ set_active_frame (frame);
+ }
ignore_badwindow--;
@@ -183,11 +186,11 @@ destroy_window (XDestroyWindowEvent *ev)
frame = find_windows_frame (win);
if (frame) cleanup_frame (frame);
- if (win == current_window())
+ if (frame == rp_current_frame)
{
PRINT_DEBUG ("Destroying the current window.\n");
- set_active_window (find_window_other ());
+ set_active_frame (frame);
unmanage (win);
}
else
@@ -310,6 +313,20 @@ client_msg (XClientMessageEvent *ev)
}
static void
+grab_rat ()
+{
+ XGrabPointer (dpy, current_screen()->root, True, 0,
+ GrabModeAsync, GrabModeAsync,
+ None, current_screen()->rat, CurrentTime);
+}
+
+static void
+ungrab_rat ()
+{
+ XUngrabPointer (dpy, CurrentTime);
+}
+
+static void
handle_key (screen_info *s)
{
char *keysym_name;
@@ -329,6 +346,10 @@ handle_key (screen_info *s)
XGetInputFocus (dpy, &fwin, &revert);
XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime);
+ /* Change the mouse icon to indicate to the user we are waiting for
+ more keystrokes */
+ grab_rat();
+
read_key (&keysym, &mod, NULL, 0);
if ((key_action = find_keybinding (keysym, mod)))
@@ -352,6 +373,8 @@ handle_key (screen_info *s)
free (msg);
}
+
+ ungrab_rat();
}
void
diff --git a/src/main.c b/src/main.c
index cd79f69..9f4ff3d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -37,6 +37,19 @@
static void init_screen (screen_info *s, int screen_num);
+/* When a user hits the prefix key, the rat switches to a different
+ pixmap to indicate that ratpoison expects the user to hit another
+ key, these are the pixmaps. */
+static unsigned char rp_rat_bits[] = {
+ 0x00, 0x00, 0xfe, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,
+ 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40,
+ 0x02, 0x40, 0x02, 0x40, 0xfe, 0x7f, 0x00, 0x00};
+
+static unsigned char rp_rat_mask_bits[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
int rat_x;
int rat_y;
int rat_visible = 1; /* rat is visible by default */
@@ -139,6 +152,9 @@ alrm_handler (int signum)
{
hide_bar (&screens[i]);
}
+
+ hide_frame_indicator();
+
XSync (dpy, False);
}
@@ -435,6 +451,27 @@ main (int argc, char *argv[])
}
static void
+init_rat_cursor (screen_info *s)
+{
+ Pixmap fore, mask;
+ XColor fg, bg, dummy;
+
+ XAllocNamedColor(dpy, DefaultColormap(dpy, s->screen_num),
+ "black", &fg, &dummy);
+ XAllocNamedColor(dpy, DefaultColormap(dpy, s->screen_num),
+ "white", &bg, &dummy);
+
+ fore = XCreatePixmapFromBitmapData (dpy, s->root,
+ rp_rat_bits, RAT_WIDTH, RAT_HEIGHT,
+ 1, 0, 1);
+ mask = XCreatePixmapFromBitmapData (dpy, s->root,
+ rp_rat_mask_bits, RAT_WIDTH, RAT_HEIGHT,
+ 1, 0, 1);
+ s->rat = XCreatePixmapCursor(dpy, fore, mask,
+ &fg, &bg, RAT_HOT_X, RAT_HOT_Y);
+}
+
+static void
init_screen (screen_info *s, int screen_num)
{
XColor fg_color, bg_color,/* bold_color, */ junk;
@@ -444,6 +481,8 @@ init_screen (screen_info *s, int screen_num)
s->def_cmap = DefaultColormap (dpy, screen_num);
s->font = font;
XGetWindowAttributes (dpy, s->root, &s->root_attr);
+
+ init_rat_cursor (s);
/* Get our program bar colors */
if (!XAllocNamedColor (dpy, s->def_cmap, FOREGROUND, &fg_color, &junk))
@@ -508,7 +547,6 @@ init_screen (screen_info *s, int screen_num)
XSelectInput (dpy, s->frame_window, KeyPressMask );
XMapRaised (dpy, s->frame_window);
-
XSync (dpy, 0);
scanwins (s);
diff --git a/src/split.c b/src/split.c
index a257921..0533de0 100644
--- a/src/split.c
+++ b/src/split.c
@@ -21,6 +21,8 @@
* Functions for handling window splitting and tiling.
*/
+#include <unistd.h>
+
#include "ratpoison.h"
rp_window_frame *rp_window_frame_sentinel;
@@ -175,14 +177,6 @@ find_window_for_frame (rp_window_frame *frame)
return most_recent;
}
-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
@@ -202,6 +196,8 @@ split_frame (rp_window_frame *frame, int way)
rp_window_frame_sentinel->prev = new_frame;
new_frame->next = rp_window_frame_sentinel;
+ new_frame->win = NULL;
+
if (way)
{
new_frame->x = frame->x;
@@ -242,7 +238,7 @@ split_frame (rp_window_frame *frame, int way)
maximize (frame->win);
XRaiseWindow (dpy, frame->win->w);
- update_frame_indicator();
+ show_frame_indicator();
}
/* Splits the window vertically in 2. */
@@ -471,10 +467,15 @@ remove_frame (rp_window_frame *frame)
void
set_active_frame (rp_window_frame *frame)
{
+ rp_window_frame *old = rp_current_frame;
+
give_window_focus (frame->win);
rp_current_frame = frame;
- update_frame_indicator();
+ if (!frame->win || old != rp_current_frame)
+ {
+ show_frame_indicator();
+ }
if( !frame->win )
{
@@ -482,3 +483,43 @@ set_active_frame (rp_window_frame *frame)
RevertToPointerRoot, CurrentTime);
}
}
+
+static void
+update_frame_indicator ()
+{
+ screen_info *s = current_screen ();
+ int width, height;
+
+ width = BAR_X_PADDING * 2 + XTextWidth (s->font, FRAME_STRING, strlen (FRAME_STRING));
+ height = (FONT_HEIGHT (s->font) + BAR_Y_PADDING * 2);
+
+ XMoveResizeWindow (dpy, current_screen()->frame_window,
+ rp_current_frame->x + rp_current_frame->width / 2 - width / 2,
+ rp_current_frame->y + rp_current_frame->height / 2 - height / 2,
+ width, height);
+
+ XClearWindow (dpy, s->frame_window);
+ XDrawString (dpy, s->frame_window, s->normal_gc,
+ BAR_X_PADDING,
+ BAR_Y_PADDING + s->font->max_bounds.ascent,
+ FRAME_STRING, strlen (FRAME_STRING));
+}
+
+void
+hide_frame_indicator ()
+{
+ /* Only hide the frame indicator if a window occupies the frame */
+ if (rp_current_frame->win)
+ {
+ XUnmapWindow (dpy, current_screen()->frame_window);
+ }
+}
+
+void
+show_frame_indicator ()
+{
+ XMapRaised (dpy, current_screen()->frame_window);
+
+ update_frame_indicator();
+ alarm (FRAME_INDICATOR_TIMEOUT);
+}
diff --git a/src/split.h b/src/split.h
index 2fa1557..6ef0186 100644
--- a/src/split.h
+++ b/src/split.h
@@ -33,5 +33,7 @@ rp_window_frame *find_frame_prev (rp_window_frame *frame);
rp_window *current_window ();
void init_frame_list ();
void set_active_frame (rp_window_frame *frame);
+void show_frame_indicator ();
+void hide_frame_indicator ();
#endif