summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog104
-rw-r--r--NEWS23
-rw-r--r--src/actions.c535
-rw-r--r--src/actions.h13
-rw-r--r--src/bar.c32
-rw-r--r--src/conf.h51
-rw-r--r--src/data.h61
-rw-r--r--src/events.c36
-rw-r--r--src/input.c20
-rw-r--r--src/list.c137
-rw-r--r--src/list.h5
-rw-r--r--src/main.c85
-rw-r--r--src/manage.c246
-rw-r--r--src/messages.h29
-rw-r--r--src/split.c20
15 files changed, 1076 insertions, 321 deletions
diff --git a/ChangeLog b/ChangeLog
index 9625339..798eb9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,107 @@
+2001-09-08 shawn <sabetts@diggin.lamenet.tmp>
+
+ * src/list.h (update_window_position): new prototype
+ (window_name): new prototype
+ (get_window_list): update prototype
+
+ * src/events.c (grab_rat): Don't wrap in an #ifdef
+ (ungrab_rat): likewise
+ (handle_key): record if the rat is grabbed and only ungrab it at
+ the end if it was first grabbed.
+
+ * src/actions.h (cmd_pos): new prototype
+ (cmd_defwinpos): new prototype
+ (cmd_deftranspos): new prototype
+ (cmd_defmaxsizepos): new prototype
+ (cmd_defbartimeout): new prototype
+ (cmd_defbarloc): new prototype
+ (cmd_deffont): new prototype
+ (cmd_defpadding): new prototype
+ (cmd_defborder): new prototype
+ (cmd_definputwidth): new prototype
+ (cmd_defwaitcursor): new prototype
+ (cmd_defwinfmt): new prototype
+ (cmd_defwinname): new prototype
+
+ * src/messages.h (MESSAGE_FRAME_STRING): new message
+
+ * src/manage.c (get_wmname): renamed from get_window_name
+ (get_class_hints): new function
+ (get_res_name): likewise
+ (get_res_class): likewise
+ (update_window_name): update the window's wm_name, res_name, and
+ res_class fields.
+ (update_window_name): calls functions get_wmname, get_res_name,
+ get_res_class.
+ (update_window_name): Don't crop the window name.
+ (update_window_information): call update_window_position.
+ (move_window): new function
+ (maximize_transient): only set the window's width and height
+ fields.
+ (maximize_normal): likewise
+ (maximize): call move_window
+ (force_maximize): likewise
+ (force_maximize): if the window has resize hints, resize it 1
+ resize unit.
+
+ * src/main.c: new global variable, defaults. remove static
+ variable, font, and move to defaults. Dependant code updated.
+ (init_defaults): new function
+ (main): call init_defaults.
+ (init_screen): initialize the screen's fg_color to black and
+ bg_color to white.
+
+ * src/list.c (free_window): free the fields user_name, res_name,
+ res_class, and wm_name.
+ (update_window_position): new function
+ (window_name): new function. Code accessing a window's name uses
+ this function. All code updated.
+ (add_to_window_list): call update_window_position
+ (add_to_window_list): initialize wm_name, res_name, and res_class
+ for the new window.
+ (format_window_name): new function
+ (get_window_list): Add parameter fmt. All callers updated.
+ (get_window_list): call format_window_name.
+
+ * src/conf.h: move Configuration variables to the global variable,
+ defaults. Dependant code updated.
+
+ * src/data.h (TOP_LEFT): new define
+ (TOP_CENTER): likewise
+ (TOP_RIGHT): likewise
+ (CENTER_LEFT): likewise
+ (CENTER_CENTER): likewise
+ (CENTER_RIGHT): likewise
+ (BOTTOM_LEFT): likewise
+ (BOTTOM_CENTER): likewise
+ (BOTTOM_RIGHT): likewise
+ (struct rp_window): new fields user_name, wm_name, res_name,
+ res_class, position.
+ (struct rp_window): remove field name. Replaced with
+ user_name. Dependant code updated.
+ (struct screen_info): remove field font. dependant code updated.
+ (struct screen_info): new fields fg_color, bg_color.
+ (struct rp_defaults): new struct
+ (defaults): new global
+
+ * src/actions.c (parse_winpos): new function
+ (cmd_pos): likewise
+ (cmd_defwinpos): likewise
+ (cmd_deftranspos): likewise
+ (cmd_defmaxsizepos): likewise
+ (cmd_defbartimeout): likewise
+ (cmd_defbarloc): likewise
+ (cmd_deffont): likewise
+ (cmd_defpadding): likewise
+ (cmd_defborder): likewise
+ (cmd_definputwidth): likewise
+ (cmd_defwaitcursor): likewise
+ (cmd_defwinfmt): likewise
+ (cmd_defwinname): likewise
+ (user_commands): New commands defbarloc, defbartimeout, defborder,
+ deffont, defintputwidth, defmaxsizepos, defpadding, deftranspos,
+ defwaitcursor, defwinfmt, defwinname, defwinpos.
+
2001-09-06 shawn <sabetts@diggin.lamenet.tmp>
* configure.in: Use AC_CHECK_FUNCS to check for getopt and
diff --git a/NEWS b/NEWS
index 099f6f9..f99bd89 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,28 @@
ratpoison NEWS --- history of user-visible changes. -*- outline -*-
+* Changes since 1.0.0
+** conf.h compile-time customizations moved
+They are now accessible through the def* suite of commands.
+
+** Window alignment
+Windows can now be aligned so they stick to the top-left corner of the
+screen, the center of the screen, the bottom-right, etc. Use the `pos'
+command. There is a customizable default setting for each of the three
+'kinds' of windows: `defwinpos' for normal windows, `deftranspos' for
+transient windows, and `defmaxsizepos' for normal windows with
+maximimum size hints.
+
+** Window format string
+The format of the list of windows dumped by the `windows' command is
+now customizable with `defwinfmt'.
+
+** Different Window naming schemes
+Windows now have 3 resources that can be used as their default name:
+the WMNAME hint which generally contains transient information such as
+what file is currently open, the res_name from the WMCLASS hint, or
+the res_class the WMCLASS hint. This affects commands like `select'
+which search for a window by name.
+
* Changes since 0.1.1
** new conf.h customization MAXSIZE_WINDOWS_ARE_TRANSIENTS
diff --git a/src/actions.c b/src/actions.c
index 74196d5..1d3509e 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -30,6 +30,84 @@ static rp_action *key_actions;
static int key_actions_last;
static int key_actions_table_size;
+static user_command user_commands[] =
+ { {"abort", cmd_abort, arg_VOID},
+ {"banish", cmd_banish, arg_VOID},
+ {"bind", cmd_bind, arg_VOID},
+ {"clock", cmd_clock, arg_VOID},
+ {"colon", cmd_colon, arg_STRING},
+ {"curframe", cmd_curframe, arg_VOID},
+ {"delete", cmd_delete, arg_VOID},
+ {"echo", cmd_echo, arg_STRING},
+ {"escape", cmd_escape, arg_STRING},
+ {"exec", cmd_exec, arg_STRING},
+ {"focus", cmd_next_frame, arg_VOID},
+ {"generate", cmd_generate, arg_STRING}, /* rename to stuff */
+ {"help", cmd_help, arg_VOID},
+ {"hsplit", cmd_h_split, arg_VOID},
+ {"kill", cmd_kill, arg_VOID},
+ {"maximize", cmd_maximize, arg_VOID},
+ {"newwm", cmd_newwm, arg_STRING},
+ {"next", cmd_next, arg_VOID},
+ {"number", cmd_number, arg_STRING},
+ {"only", cmd_only, arg_VOID},
+ {"other", cmd_other, arg_VOID},
+ {"pos", cmd_pos, arg_STRING},
+ {"prev", cmd_prev, arg_VOID},
+ {"quit", cmd_quit, arg_VOID},
+ {"remove", cmd_remove, arg_VOID},
+ {"rudeness", cmd_rudeness, arg_STRING},
+ {"select", cmd_select, arg_STRING},
+ {"source", cmd_source, arg_STRING},
+ {"split", cmd_h_split, arg_VOID},
+ {"title", cmd_rename, arg_STRING},
+ {"unbind", cmd_unbind, arg_STRING},
+ {"version", cmd_version, arg_VOID},
+ {"vsplit", cmd_v_split, arg_VOID},
+ {"windows", cmd_windows, arg_VOID},
+
+ /* Commands to set default behavior. */
+ {"defbarloc", cmd_defbarloc, arg_STRING},
+ {"defbartimeout", cmd_defbartimeout, arg_STRING},
+ {"defborder", cmd_defborder, arg_STRING},
+ {"deffont", cmd_deffont, arg_STRING},
+ {"definputwidth", cmd_definputwidth, arg_STRING},
+ {"defmaxsizepos", cmd_defmaxsizepos, arg_STRING},
+ {"defpadding", cmd_defpadding, arg_STRING},
+ {"deftranspos", cmd_deftranspos, arg_STRING},
+ {"defwaitcursor", cmd_defwaitcursor, arg_STRING},
+ {"defwinfmt", cmd_defwinfmt, arg_STRING},
+ {"defwinname", cmd_defwinname, arg_STRING},
+ {"defwinpos", cmd_defwinpos, arg_STRING},
+
+ /* Commands to help debug ratpoison. */
+#ifdef DEBUG
+#endif
+
+ /* the following screen commands may or may not be able to be
+ implemented. See the screen documentation for what should be
+ emulated with these commands */
+#if 0
+ {"hardcopy", cmd_unimplemented, arg_VOID},
+ {"lastmsg", cmd_unimplemented, arg_VOID},
+ {"license", cmd_unimplemented, arg_VOID},
+ {"lockscreen", cmd_unimplemented, arg_VOID},
+ {"meta", cmd_unimplemented, arg_VOID},
+ {"msgminwait", cmd_unimplemented, arg_VOID},
+ {"msgwait", cmd_unimplemented, arg_VOID},
+ {"nethack", cmd_unimplemented, arg_VOID},
+ {"redisplay", cmd_unimplemented, arg_VOID},
+ {"screen", cmd_unimplemented, arg_VOID},
+ {"setenv", cmd_unimplemented, arg_VOID},
+ {"shell", cmd_unimplemented, arg_VOID},
+ {"shelltitle", cmd_unimplemented, arg_VOID},
+ {"sleep", cmd_unimplemented, arg_VOID},
+ {"sorendition", cmd_unimplemented, arg_VOID},
+ {"startup_message", cmd_unimplemented, arg_VOID},
+ {"stuff", cmd_unimplemented, arg_VOID},
+#endif
+ {0, 0, 0} };
+
rp_action*
find_keybinding_by_action (char *action)
{
@@ -184,65 +262,6 @@ initialize_default_keybindings (void)
add_keybinding (XK_question, 0, "help");
}
-user_command user_commands[] =
- { {"abort", cmd_abort, arg_VOID},
- {"next", cmd_next, arg_VOID},
- {"prev", cmd_prev, arg_VOID},
- {"exec", cmd_exec, arg_STRING},
- {"select", cmd_select, arg_STRING},
- {"colon", cmd_colon, arg_STRING},
- {"kill", cmd_kill, arg_VOID},
- {"delete", cmd_delete, arg_VOID},
- {"other", cmd_other, arg_VOID},
- {"windows", cmd_windows, arg_VOID},
- {"title", cmd_rename, arg_STRING},
- {"clock", cmd_clock, arg_VOID},
- {"maximize", cmd_maximize, arg_VOID},
- {"newwm", cmd_newwm, arg_STRING},
- {"generate", cmd_generate, arg_STRING}, /* rename to stuff */
- {"version", cmd_version, arg_VOID},
- {"bind", cmd_bind, arg_VOID},
- {"unbind", cmd_unbind, arg_STRING},
- {"source", cmd_source, arg_STRING},
- {"escape", cmd_escape, arg_STRING},
- {"echo", cmd_echo, arg_STRING},
- {"split", cmd_h_split, arg_VOID},
- {"hsplit", cmd_h_split, arg_VOID},
- {"vsplit", cmd_v_split, arg_VOID},
- {"focus", cmd_next_frame, arg_VOID},
- {"only", cmd_only, arg_VOID},
- {"remove", cmd_remove, arg_VOID},
- {"banish", cmd_banish, arg_VOID},
- {"curframe", cmd_curframe, arg_VOID},
- {"help", cmd_help, arg_VOID},
- {"quit", cmd_quit, arg_VOID},
- {"number", cmd_number, arg_STRING},
- {"rudeness", cmd_rudeness, arg_STRING},
-
- /* the following screen commands may or may not be able to be
- implemented. See the screen documentation for what should be
- emulated with these commands */
-#if 0
- {"stuff", cmd_unimplemented, arg_VOID},
- {"hardcopy", cmd_unimplemented, arg_VOID},
- {"lastmsg", cmd_unimplemented, arg_VOID},
- {"license", cmd_unimplemented, arg_VOID},
- {"lockscreen", cmd_unimplemented, arg_VOID},
- {"meta", cmd_unimplemented, arg_VOID},
- {"msgwait", cmd_unimplemented, arg_VOID},
- {"msgminwait", cmd_unimplemented, arg_VOID},
- {"nethack", cmd_unimplemented, arg_VOID},
- {"redisplay", cmd_unimplemented, arg_VOID},
- {"screen", cmd_unimplemented, arg_VOID},
- {"setenv", cmd_unimplemented, arg_VOID},
- {"shell", cmd_unimplemented, arg_VOID},
- {"shelltitle", cmd_unimplemented, arg_VOID},
- {"sleep", cmd_unimplemented, arg_VOID},
- {"sorendition", cmd_unimplemented, arg_VOID},
- {"startup_message", cmd_unimplemented, arg_VOID},
-#endif
- {0, 0, 0} };
-
/* return a KeySym from a string that contains either a hex value or
an X keysym description */
static int string_to_keysym (char *str)
@@ -680,10 +699,10 @@ cmd_rename (int interactive, void *data)
if (*winname)
{
- free (current_window()->name);
- current_window()->name = xmalloc (sizeof (char) * strlen (winname) + 1);
+ free (current_window()->user_name);
+ current_window()->user_name = xmalloc (sizeof (char) * strlen (winname) + 1);
- strcpy (current_window()->name, winname);
+ strcpy (current_window()->user_name, winname);
current_window()->named = 1;
@@ -987,7 +1006,7 @@ cmd_windows (int interactive, void *data)
else
{
window_list = sbuf_new (0);
- get_window_list ("\n", window_list, &dummy, &dummy);
+ get_window_list (defaults.window_fmt, "\n", window_list, &dummy, &dummy);
tmp = sbuf_get (window_list);
free (window_list);
@@ -1153,23 +1172,23 @@ cmd_help (int interactive, void *data)
XSetInputFocus (dpy, s->help_window, RevertToPointerRoot, CurrentTime);
XDrawString (dpy, s->help_window, s->normal_gc,
- 10, y + s->font->max_bounds.ascent,
+ 10, y + defaults.font->max_bounds.ascent,
"ratpoison key bindings", strlen ("ratpoison key bindings"));
- y += FONT_HEIGHT (s->font) * 2;
+ y += FONT_HEIGHT (defaults.font) * 2;
XDrawString (dpy, s->help_window, s->normal_gc,
- 10, y + s->font->max_bounds.ascent,
+ 10, y + defaults.font->max_bounds.ascent,
"Command key: ", strlen ("Command key: "));
keysym_name = keysym_to_string (prefix_key.sym, prefix_key.state);
XDrawString (dpy, s->help_window, s->normal_gc,
- 10 + XTextWidth (s->font, "Command key: ", strlen ("Command key: ")),
- y + s->font->max_bounds.ascent,
+ 10 + XTextWidth (defaults.font, "Command key: ", strlen ("Command key: ")),
+ y + defaults.font->max_bounds.ascent,
keysym_name, strlen (keysym_name));
free (keysym_name);
- y += FONT_HEIGHT (s->font) * 2;
+ y += FONT_HEIGHT (defaults.font) * 2;
i = 0;
old_i = 0;
@@ -1180,12 +1199,12 @@ cmd_help (int interactive, void *data)
keysym_name = keysym_to_string (key_actions[i].key, key_actions[i].state);
XDrawString (dpy, s->help_window, s->normal_gc,
- x, y + s->font->max_bounds.ascent,
+ x, y + defaults.font->max_bounds.ascent,
keysym_name, strlen (keysym_name));
- if (XTextWidth (s->font, keysym_name, strlen (keysym_name)) > max_width)
+ if (XTextWidth (defaults.font, keysym_name, strlen (keysym_name)) > max_width)
{
- max_width = XTextWidth (s->font, keysym_name, strlen (keysym_name));
+ max_width = XTextWidth (defaults.font, keysym_name, strlen (keysym_name));
}
free (keysym_name);
@@ -1193,16 +1212,16 @@ cmd_help (int interactive, void *data)
else
{
XDrawString (dpy, s->help_window, s->normal_gc,
- x, y + s->font->max_bounds.ascent,
+ x, y + defaults.font->max_bounds.ascent,
key_actions[i].data, strlen (key_actions[i].data));
- if (XTextWidth (s->font, key_actions[i].data, strlen (key_actions[i].data)) > max_width)
+ if (XTextWidth (defaults.font, key_actions[i].data, strlen (key_actions[i].data)) > max_width)
{
- max_width = XTextWidth (s->font, key_actions[i].data, strlen (key_actions[i].data));
+ max_width = XTextWidth (defaults.font, key_actions[i].data, strlen (key_actions[i].data));
}
}
- y += FONT_HEIGHT (s->font);
+ y += FONT_HEIGHT (defaults.font);
if (y > s->root_attr.height)
{
if (drawing_keys)
@@ -1219,7 +1238,7 @@ cmd_help (int interactive, void *data)
}
max_width = 0;
- y = FONT_HEIGHT (s->font) * 4;
+ y = FONT_HEIGHT (defaults.font) * 4;
}
else
{
@@ -1228,7 +1247,7 @@ cmd_help (int interactive, void *data)
{
x += max_width + 10;
drawing_keys = 0;
- y = FONT_HEIGHT (s->font) * 4;
+ y = FONT_HEIGHT (defaults.font) * 4;
i = old_i;
max_width = 0;
}
@@ -1266,3 +1285,363 @@ cmd_rudeness (int interactive, void *data)
return NULL;
}
+
+static int
+parse_winpos (char *data)
+{
+ int ret = 0;
+ char *x, *y;
+
+ x = xmalloc (strlen (data) + 1);
+ y = xmalloc (strlen (data) + 1);
+
+ if (sscanf (data, "%s %s", x , y) < 2)
+ {
+ message (" pos: Two arguments needed ");
+ free (x);
+ free (y);
+ return -3;
+ }
+
+ PRINT_DEBUG ("%s %s\n", x, y);
+
+ switch (y[0])
+ {
+ case 't':
+ case 'T':
+ ret = TOP_LEFT;
+ break;
+
+ case 'c':
+ case 'C':
+ ret = CENTER_LEFT;
+ break;
+
+ case 'b':
+ case 'B':
+ ret = BOTTOM_LEFT;
+ break;
+
+ default:
+ ret = -1;
+ goto done;
+ break;
+ }
+
+ switch (x[0])
+ {
+ case 'l':
+ case 'L':
+ break;
+
+ case 'c':
+ case 'C':
+ ret += TOP_CENTER;
+ break;
+
+ case 'r':
+ case 'R':
+ ret += TOP_RIGHT;
+ break;
+
+ default:
+ ret = -2;
+ goto done;
+ break;
+ }
+
+ done:
+ free (x);
+ free (y);
+
+ return ret;
+}
+
+char *
+cmd_pos (int interactive, void *data)
+{
+ int pos;
+ rp_window *win;
+
+ if (current_window() == NULL) return NULL;
+ if (data == NULL)
+ {
+ message (" pos: Two arguments needed ");
+ return NULL;
+ }
+
+ win = current_window();
+
+ if ((pos = parse_winpos (data)) < 0)
+ {
+ message (" pos: Unknown position ");
+ }
+ else
+ {
+ win->position = pos;
+ maximize (win);
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defwinpos (int interactive, void *data)
+{
+ int pos;
+
+ if ((pos = parse_winpos (data)) < 0)
+ {
+ message (" pos: Unknown position ");
+ }
+ else
+ {
+ defaults.win_pos = pos;
+ }
+
+ return NULL;
+}
+
+char *
+cmd_deftranspos (int interactive, void *data)
+{
+ int pos;
+
+ if ((pos = parse_winpos (data)) < 0)
+ {
+ message (" pos: Unknown position ");
+ }
+ else
+ {
+ defaults.trans_pos = pos;
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defmaxsizepos (int interactive, void *data)
+{
+ int pos;
+
+ if ((pos = parse_winpos (data)) < 0)
+ {
+ message (" pos: Unknown position ");
+ }
+ else
+ {
+ defaults.maxsize_pos = pos;
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defbartimeout (int interactive, void *data)
+{
+ if (data == NULL) return NULL;
+
+ if (sscanf (data, "%d", &defaults.bar_timeout) < 1)
+ {
+ message (" defbartimeout: One argument required ");
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defbarloc (int interactive, void *data)
+{
+ int loc;
+
+ if (data == NULL) return NULL;
+
+ if (sscanf (data, "%d", &loc) < 1)
+ {
+ message (" defbarloc: One argument required ");
+ return NULL;
+ }
+
+ switch (loc)
+ {
+ case 0:
+ defaults.bar_location = TOP_LEFT;
+ break;
+ case 1:
+ defaults.bar_location = TOP_RIGHT;
+ break;
+ case 2:
+ defaults.bar_location = BOTTOM_RIGHT;
+ break;
+ case 3:
+ defaults.bar_location = BOTTOM_LEFT;
+ break;
+
+ default:
+ message (" defbarloc: Unknown location ");
+ break;
+ }
+
+ return NULL;
+}
+
+char *
+cmd_deffont (int interactive, void *data)
+{
+ XFontStruct *font;
+
+ if (data == NULL) return NULL;
+
+ font = XLoadQueryFont (dpy, (char *)data);
+ if (font == NULL)
+ {
+ message (" deffont: Unknown font ");
+ return NULL;
+ }
+
+ /* Save the font as the default. */
+ XFreeFont (dpy, defaults.font);
+ defaults.font = font;
+
+ return NULL;
+}
+
+char *
+cmd_defpadding (int interactive, void *data)
+{
+ rp_window_frame *frame;
+ int l, t, r, b;
+
+ if (data == NULL)
+ {
+ message (" defpadding: Four arguments required ");
+ return NULL;
+ }
+
+ if (sscanf (data, "%d %d %d %d", &l, &t, &r, &b) < 4)
+ {
+ message (" defpadding: Four arguments required ");
+ return NULL;
+ }
+
+ /* Resize the frames to make sure they are not too big and not too
+ small. */
+ for (frame = rp_window_frame_sentinel->next;
+ frame != rp_window_frame_sentinel;
+ frame = frame->next)
+ {
+ int bk_pos, bk_len;
+
+ /* Resize horizontally. */
+ bk_pos = frame->x;
+ bk_len = frame->width;
+
+ if (frame->x == defaults.padding_left)
+ {
+ frame->x = l;
+ frame->width += bk_pos - l;
+ }
+
+ if (bk_pos + bk_len == current_screen()->root_attr.width - defaults.padding_right)
+ frame->width = current_screen()->root_attr.width - r - frame->x;
+
+ /* Resize vertically. */
+ bk_pos = frame->y;
+ bk_len = frame->height;
+
+ if (frame->y == defaults.padding_top)
+ {
+ frame->y = t;
+ frame->height += bk_pos - t;
+ }
+
+ if (bk_pos + bk_len == current_screen()->root_attr.height - defaults.padding_bottom)
+ frame->height = current_screen()->root_attr.height - b - frame->y;
+
+ maximize_all_windows_in_frame (frame);
+ }
+
+ defaults.padding_left = l;
+ defaults.padding_right = r;
+ defaults.padding_top = t;
+ defaults.padding_bottom = b;
+
+ return NULL;
+}
+
+char *
+cmd_defborder (int interactive, void *data)
+{
+ rp_window *win;
+
+ if (data == NULL) return NULL;
+
+ if (sscanf (data, "%d", &defaults.window_border_width) < 1)
+ {
+ message (" defborder: One argument required ");
+ }
+
+ /* Update all the visible windows. */
+ for (win = rp_mapped_window_sentinel->next;
+ win != rp_mapped_window_sentinel;
+ win = win->next)
+ {
+ if (win->frame)
+ maximize (win);
+ }
+
+ return NULL;
+}
+
+char *
+cmd_definputwidth (int interactive, void *data)
+{
+ if (data == NULL
+ || sscanf (data, "%d", &defaults.input_window_size) < 1)
+ {
+ message (" definputwidth: One argument required ");
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defwaitcursor (int interactive, void *data)
+{
+ if (data == NULL
+ || sscanf (data, "%d", &defaults.wait_for_key_cursor) < 1)
+ {
+ message (" defwaitforkey: One argument required ");
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defwinfmt (int interactive, void *data)
+{
+ if (data == NULL) return NULL;
+
+ free (defaults.window_fmt);
+ defaults.window_fmt = strdup (data);
+
+ if (defaults.window_fmt == NULL)
+ {
+ PRINT_ERROR ("Not enough memory\n");
+ exit (EXIT_FAILURE);
+ }
+
+ return NULL;
+}
+
+char *
+cmd_defwinname (int interactive, void *data)
+{
+ if (data == NULL
+ || sscanf (data, "%d", &defaults.win_name) < 1)
+ {
+ message (" defwinname: One argument required ");
+ }
+
+ return NULL;
+}
diff --git a/src/actions.h b/src/actions.h
index 4c0f777..1834fc0 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -75,6 +75,19 @@ char * cmd_quit(int interactive, void *data);
char * cmd_number (int interactive, void *data);
char * cmd_rudeness (int interactive, void *data);
char * cmd_unbind (int interactive, void *data);
+char * cmd_pos (int interactive, void *data);
+char * cmd_defwinpos (int interactive, void *data);
+char * cmd_deftranspos (int interactive, void *data);
+char * cmd_defmaxsizepos (int interactive, void *data);
+char * cmd_defbartimeout (int interactive, void *data);
+char * cmd_defbarloc (int interactive, void *data);
+char * cmd_deffont (int interactive, void *data);
+char * cmd_defpadding (int interactive, void *data);
+char * cmd_defborder (int interactive, void *data);
+char * cmd_definputwidth (int interactive, void *data);
+char * cmd_defwaitcursor (int interactive, void *data);
+char * cmd_defwinfmt (int interactive, void *data);
+char * cmd_defwinname (int interactive, void *data);
/* void cmd_xterm (void *data); */
diff --git a/src/bar.c b/src/bar.c
index 7dbe1cd..89df8d1 100644
--- a/src/bar.c
+++ b/src/bar.c
@@ -64,7 +64,7 @@ show_bar (screen_info *s)
update_window_names (s);
/* Set an alarm to auto-hide the bar BAR_TIMEOUT seconds later */
- alarm (BAR_TIMEOUT);
+ alarm (defaults.bar_timeout);
alarm_signalled = 0;
return 1;
}
@@ -78,15 +78,21 @@ show_bar (screen_info *s)
int
bar_x (screen_info *s, int width)
{
- if (BAR_LOCATION >= 2) return s->root_attr.width - width - 2;
- else return 0;
+ if (defaults.bar_location == BOTTOM_RIGHT
+ || defaults.bar_location == TOP_RIGHT)
+ return s->root_attr.width - width - 2;
+ else
+ return 0;
}
int
bar_y (screen_info *s)
{
- if (BAR_LOCATION % 2) return 0;
- else return s->root_attr.height - (FONT_HEIGHT (s->font) + BAR_Y_PADDING * 2) - 2;
+ if (defaults.bar_location == TOP_LEFT
+ || defaults.bar_location == TOP_RIGHT )
+ return 0;
+ else
+ return s->root_attr.height - (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2) - 2;
}
void
@@ -102,7 +108,7 @@ update_window_names (screen_info *s)
if (bar_buffer == NULL)
bar_buffer = sbuf_new (0);
- get_window_list (NULL, bar_buffer, &mark_start, &mark_end);
+ get_window_list (defaults.window_fmt, NULL, bar_buffer, &mark_start, &mark_end);
marked_message (sbuf_get (bar_buffer), mark_start, mark_end);
}
@@ -141,8 +147,8 @@ marked_message (char *msg, int mark_start, int mark_end)
unsigned long mask;
screen_info *s = current_screen ();
- int width = BAR_X_PADDING * 2 + XTextWidth (s->font, msg, strlen (msg));
- int height = (FONT_HEIGHT (s->font) + BAR_Y_PADDING * 2);
+ int width = defaults.bar_x_padding * 2 + XTextWidth (defaults.font, msg, strlen (msg));
+ int height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2);
PRINT_DEBUG ("%s\n", msg);
@@ -154,7 +160,7 @@ marked_message (char *msg, int mark_start, int mark_end)
}
/* Reset the alarm to auto-hide the bar in BAR_TIMEOUT seconds. */
- alarm (BAR_TIMEOUT);
+ alarm (defaults.bar_timeout);
alarm_signalled = 0;
XMoveResizeWindow (dpy, s->bar_window,
@@ -166,8 +172,8 @@ marked_message (char *msg, int mark_start, int mark_end)
XRaiseWindow (dpy, s->bar_window);
XDrawString (dpy, s->bar_window, s->normal_gc,
- BAR_X_PADDING,
- BAR_Y_PADDING + s->font->max_bounds.ascent,
+ defaults.bar_x_padding,
+ defaults.bar_y_padding + defaults.font->max_bounds.ascent,
msg, strlen (msg));
@@ -198,8 +204,8 @@ marked_message (char *msg, int mark_start, int mark_end)
int start;
int end;
- start = XTextWidth (s->font, msg, mark_start) + BAR_X_PADDING;
- end = XTextWidth (s->font, msg + mark_start, mark_end - mark_start) + BAR_X_PADDING;
+ start = XTextWidth (defaults.font, msg, mark_start) + defaults.bar_x_padding;
+ end = XTextWidth (defaults.font, msg + mark_start, mark_end - mark_start) + defaults.bar_x_padding;
PRINT_DEBUG ("%d %d strlen(%d)==> %d %d\n", mark_start, mark_end, strlen(msg), start, end);
diff --git a/src/conf.h b/src/conf.h
index 32d4041..d3e6043 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -32,56 +32,10 @@
#define INPUT_ABORT_KEY XK_g
#define INPUT_ABORT_MODIFIER ControlMask
-/* After hitting the prefix key ratpoison will change the mouse cursor
- to a square to indicate that it is waiting for a second
- keystroke. If do not wish this functionality, comment out the
- following line. */
-#define USE_WAITFORKEY_CURSOR
-
-/* Quit ratpoison when there are no more managed windows. */
-/* #define AUTO_CLOSE */
-
-/* Treat windows with maxsize hints as if they were a transient window
- (don't hide the windows underneath, and center them) */
-#define MAXSIZE_WINDOWS_ARE_TRANSIENTS
-
-/* The minimum size of the input window */
-#define INPUT_WINDOW_SIZE 200
-
-/* If you want the input window to take up the length of the screen,
- use this: */
-/* #define INPUT_WINDOW_SIZE (s->root_attr.width - prompt_width) */
-
-
-/* The border width ratpoison configures all windows with */
-#define WINDOW_BORDER_WIDTH 1
-
/* Pressing a key sends the mouse to the bottom right corner. This
doesn't work very well yet. */
/* #define HIDE_MOUSE */
-#define FOREGROUND "black"
-#define BACKGROUND "white"
-#define FONT "9x15bold"
-
-#define BAR_Y_PADDING 0 /* The amount of padding on the top
- and bottom of the message bar */
-#define BAR_X_PADDING 0 /* The amount of padding on the left
- and right of the message bar */
-#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
-#define PADDING_BOTTOM 0
-
/* If for some sick reason you don't want ratpoison to manage a
window, put its name in this list. These windows get drawn but
ratpoison won't have any knowledge of them and you won't be able to
@@ -89,9 +43,4 @@
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 6ed2d44..b29047f 100644
--- a/src/data.h
+++ b/src/data.h
@@ -44,15 +44,33 @@ struct rp_window_frame
};
+/* Possible positions for a window. */
+#define TOP_LEFT 0
+#define TOP_CENTER 1
+#define TOP_RIGHT 2
+
+#define CENTER_LEFT 3
+#define CENTER_CENTER 4
+#define CENTER_RIGHT 5
+
+#define BOTTOM_LEFT 6
+#define BOTTOM_CENTER 7
+#define BOTTOM_RIGHT 8
+
struct rp_window
{
screen_info *scr;
Window w;
int number;
- char *name;
int state;
int last_access;
int named;
+
+ /* Window name hints. */
+ char *user_name;
+ char *wm_name;
+ char *res_name;
+ char *res_class;
/* Dimensions */
int x, y, width, height, border;
@@ -70,6 +88,10 @@ struct rp_window
/* Saved mouse position */
int mouse_x, mouse_y;
+ /* The alignment of the window. To what side or corner should the
+ window stick to. */
+ int position;
+
/* 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. */
@@ -81,13 +103,13 @@ struct rp_window
struct screen_info
{
GC normal_gc;
- XFontStruct *font; /* The font we want to use. */
XWindowAttributes root_attr;
Window root, bar_window, key_window, input_window, frame_window, help_window;
int bar_is_raised;
int screen_num; /* Our screen number as dictated my X */
Colormap def_cmap;
Cursor rat;
+ unsigned long fg_color, bg_color; /* The pixel color. */
};
struct rp_action
@@ -104,6 +126,41 @@ struct rp_key
unsigned int state;
};
+struct rp_defaults
+{
+ /* Default positions for new normal windows, transient windows, and
+ normal windows with maxsize hints. */
+ int win_pos;
+ int trans_pos;
+ int maxsize_pos;
+
+ int input_window_size;
+ int window_border_width;
+
+ int bar_x_padding;
+ int bar_y_padding;
+ int bar_location;
+ int bar_timeout;
+
+ int frame_indicator_timeout;
+
+ int padding_left;
+ int padding_right;
+ int padding_top;
+ int padding_bottom;
+
+ XFontStruct *font;
+
+ int wait_for_key_cursor;
+
+ char *window_fmt;
+
+ /* Which name to use: wm_name, res_name, res_class. */
+ int win_name;
+};
+
+extern struct rp_defaults defaults;
+
/* The prefix key also known as the command character under screen. */
extern struct rp_key prefix_key;
diff --git a/src/events.c b/src/events.c
index 98ffa11..bcf1631 100644
--- a/src/events.c
+++ b/src/events.c
@@ -112,11 +112,11 @@ unmap_notify (XEvent *ev)
switch (win->state)
{
case IconicState:
- PRINT_DEBUG ("Withdrawing iconized window '%s'\n", win->name);
+ PRINT_DEBUG ("Withdrawing iconized window '%s'\n", window_name (win));
if (ev->xunmap.send_event) withdraw_window (win);
break;
case NormalState:
- PRINT_DEBUG ("Withdrawing normal window '%s'\n", win->name);
+ PRINT_DEBUG ("Withdrawing normal window '%s'\n", window_name (win));
/* If the window was inside a frame, fill the frame with another
window. */
frame = find_windows_frame (win);
@@ -182,10 +182,10 @@ map_request (XEvent *ev)
{
if (win->transient)
marked_message_printf (0, 0, MESSAGE_RAISE_TRANSIENT,
- win->number, win->name);
+ win->number, window_name (win));
else
marked_message_printf (0, 0, MESSAGE_RAISE_WINDOW,
- win->number, win->name);
+ win->number, window_name (win));
}
}
break;
@@ -223,7 +223,7 @@ configure_notify (XConfigureEvent *e)
win = find_window (e->window);
if (win)
{
- PRINT_DEBUG ("'%s' window notify: %d %d %d %d %d\n", win->name,
+ PRINT_DEBUG ("'%s' window notify: %d %d %d %d %d\n", window_name (win),
e->x, e->y, e->width, e->height, e->border_width);
}
}
@@ -269,10 +269,10 @@ configure_request (XConfigureRequestEvent *e)
{
if (win->transient)
marked_message_printf (0, 0, MESSAGE_RAISE_TRANSIENT,
- win->number, win->name);
+ win->number, window_name (win));
else
marked_message_printf (0, 0, MESSAGE_RAISE_WINDOW,
- win->number, win->name);
+ win->number, window_name (win));
}
}
else
@@ -285,7 +285,7 @@ configure_request (XConfigureRequestEvent *e)
PRINT_DEBUG("request CWStackMode %d\n", e->detail);
}
- PRINT_DEBUG ("'%s' window size: %d %d %d %d %d\n", win->name,
+ PRINT_DEBUG ("'%s' window size: %d %d %d %d %d\n", window_name (win),
win->x, win->y, win->width, win->height, win->border);
if (e->value_mask & CWBorderWidth)
@@ -368,7 +368,6 @@ client_msg (XClientMessageEvent *ev)
}
}
-#ifdef USE_WAITFORKEY_CURSOR
static void
grab_rat ()
{
@@ -376,15 +375,12 @@ grab_rat ()
GrabModeAsync, GrabModeAsync,
None, current_screen()->rat, CurrentTime);
}
-#endif
-#ifdef USE_WAITFORKEY_CURSOR
static void
ungrab_rat ()
{
XUngrabPointer (dpy, CurrentTime);
}
-#endif
static void
handle_key (screen_info *s)
@@ -395,11 +391,12 @@ handle_key (screen_info *s)
Window fwin; /* Window currently in focus */
KeySym keysym; /* Key pressed */
unsigned int mod; /* Modifiers */
+ int rat_grabbed = 0;
PRINT_DEBUG ("handling key...\n");
/* All functions hide the program bar and the frame indicator. */
- if (BAR_TIMEOUT > 0) hide_bar (s);
+ if (defaults.bar_timeout > 0) hide_bar (s);
hide_frame_indicator();
/* Disable any alarm that was going to go off. */
@@ -411,9 +408,11 @@ handle_key (screen_info *s)
/* Change the mouse icon to indicate to the user we are waiting for
more keystrokes */
-#ifdef USE_WAITFORKEY_CURSOR
- grab_rat();
-#endif
+ if (defaults.wait_for_key_cursor)
+ {
+ grab_rat();
+ rat_grabbed = 1;
+ }
read_key (&keysym, &mod, NULL, 0);
@@ -437,9 +436,8 @@ handle_key (screen_info *s)
free (keysym_name);
}
-#ifdef USE_WAITFORKEY_CURSOR
- ungrab_rat();
-#endif
+ if (rat_grabbed)
+ ungrab_rat();
}
static void
diff --git a/src/input.c b/src/input.c
index afb3c71..4e2ba4e 100644
--- a/src/input.c
+++ b/src/input.c
@@ -284,31 +284,31 @@ read_key (KeySym *keysym, unsigned int *modifiers, char *keysym_name, int len)
static void
update_input_window (screen_info *s, char *prompt, char *input, int input_len)
{
- int prompt_width = XTextWidth (s->font, prompt, strlen (prompt));
- int input_width = XTextWidth (s->font, input, input_len);
+ int prompt_width = XTextWidth (defaults.font, prompt, strlen (prompt));
+ int input_width = XTextWidth (defaults.font, input, input_len);
int width;
- width = BAR_X_PADDING * 2 + prompt_width + input_width;
+ width = defaults.bar_x_padding * 2 + prompt_width + input_width;
- if (width < INPUT_WINDOW_SIZE + prompt_width)
+ if (width < defaults.input_window_size + prompt_width)
{
- width = INPUT_WINDOW_SIZE + prompt_width;
+ width = defaults.input_window_size + prompt_width;
}
XMoveResizeWindow (dpy, s->input_window,
bar_x (s, width), bar_y (s), width,
- (FONT_HEIGHT (s->font) + BAR_Y_PADDING * 2));
+ (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2));
XClearWindow (dpy, s->input_window);
XDrawString (dpy, s->input_window, s->normal_gc,
- BAR_X_PADDING,
- BAR_Y_PADDING + s->font->max_bounds.ascent, prompt,
+ defaults.bar_x_padding,
+ defaults.bar_y_padding + defaults.font->max_bounds.ascent, prompt,
strlen (prompt));
XDrawString (dpy, s->input_window, s->normal_gc,
- BAR_X_PADDING + prompt_width,
- BAR_Y_PADDING + s->font->max_bounds.ascent, input,
+ defaults.bar_x_padding + prompt_width,
+ defaults.bar_y_padding + defaults.font->max_bounds.ascent, input,
input_len);
}
diff --git a/src/list.c b/src/list.c
index 934c657..619c907 100644
--- a/src/list.c
+++ b/src/list.c
@@ -45,12 +45,52 @@ free_window (rp_window *w)
{
if (w == NULL) return;
- free (w->name);
+ free (w->user_name);
+ free (w->res_name);
+ free (w->res_class);
+ free (w->wm_name);
+
XFree (w->hints);
free (w);
}
+void
+update_window_position (rp_window *win)
+{
+ if (win->transient)
+ win->position = defaults.trans_pos;
+ else if (win->hints->flags & PMaxSize)
+ win->position = defaults.maxsize_pos;
+ else
+ win->position = defaults.win_pos;
+}
+
+char *
+window_name (rp_window *win)
+{
+ if (win == NULL) return NULL;
+
+ if (win->named)
+ return win->user_name;
+
+ switch (defaults.win_name)
+ {
+ case 0:
+ return win->wm_name;
+
+ case 1:
+ return win->res_name;
+
+ case 2:
+ return win->res_class;
+
+ default:
+ return win->wm_name;
+ }
+
+ return NULL;
+}
/* Allocate a new window and add it to the list of managed windows */
rp_window *
@@ -72,13 +112,18 @@ add_to_window_list (screen_info *s, Window w)
new_window->transient = XGetTransientForHint (dpy, new_window->w, &new_window->transient_for);
PRINT_DEBUG ("transient %d\n", new_window->transient);
+ update_window_position (new_window);
+
get_mouse_root_position (new_window, &new_window->mouse_x, &new_window->mouse_y);
XSelectInput (dpy, new_window->w, WIN_EVENTS);
- new_window->name = xmalloc (strlen ("Unnamed") + 1);
+ new_window->user_name = xmalloc (strlen ("Unnamed") + 1);
- strcpy (new_window->name, "Unnamed");
+ strcpy (new_window->user_name, "Unnamed");
+ new_window->wm_name = NULL;
+ new_window->res_name = NULL;
+ new_window->res_class = NULL;
/* Add the window to the end of the unmapped list. */
append_to_list (new_window, rp_unmapped_window_sentinel);
@@ -177,7 +222,7 @@ find_window_name (char *name)
/* if (w->state == STATE_UNMAPPED) */
/* continue; */
- if (str_comp (name, w->name, strlen (name)))
+ if (str_comp (name, window_name (w), strlen (name)))
return w;
}
@@ -514,8 +559,8 @@ set_active_window (rp_window *win)
last_win = set_frames_window (rp_current_frame, win);
- if (last_win) PRINT_DEBUG ("last window: %s\n", last_win->name);
- PRINT_DEBUG ("new window: %s\n", win->name);
+ if (last_win) PRINT_DEBUG ("last window: %s\n", window_name (last_win));
+ PRINT_DEBUG ("new window: %s\n", window_name (win));
/* Make sure the window comes up full screen */
maximize (win);
@@ -560,18 +605,78 @@ goto_window (rp_window *win)
void
print_window_information (rp_window *win)
{
- marked_message_printf (0, 0, MESSAGE_WINDOW_INFORMATION, win->number, win->name);
+ marked_message_printf (0, 0, MESSAGE_WINDOW_INFORMATION,
+ win->number, window_name (win));
+}
+
+/* format options
+ N - Window number
+ - - Window status (current window, last window, etc)
+ W - Window Name
+ w - Window res name
+ c - Window res class
+ n - X11 Window ID
+
+ */
+static void
+format_window_name (char *fmt, rp_window *win, rp_window *other_win,
+ struct sbuf *buffer)
+{
+ char dbuf[10];
+
+ for(; *fmt; fmt++)
+ {
+ switch (*fmt)
+ {
+ case 'N':
+ snprintf (dbuf, 10, "%d", win->number);
+ sbuf_concat (buffer, dbuf);
+ break;
+
+ case '-':
+ if (win == current_window())
+ sbuf_concat (buffer, "*");
+ else if (win == other_win)
+ sbuf_concat (buffer, "+");
+ else
+ sbuf_concat (buffer, "-");
+ break;
+
+ case 'W':
+ sbuf_concat (buffer, window_name (win));
+ break;
+
+ case 'w':
+ sbuf_concat (buffer, win->res_name);
+ break;
+
+ case 'c':
+ sbuf_concat (buffer, win->res_class);
+ break;
+
+ case 'n':
+ snprintf (dbuf, 9, "%ld", (unsigned long)win->w);
+ sbuf_concat (buffer, dbuf);
+ break;
+
+ default:
+ dbuf[0] = *fmt;
+ dbuf[1] = 0;
+ sbuf_concat (buffer, dbuf);
+ break;
+ }
+ }
}
/* get the window list and store it in buffer delimiting each window
with delim. mark_start and mark_end will be filled with the text
positions for the start and end of the current window. */
void
-get_window_list (char *delim, struct sbuf *buffer, int *mark_start, int *mark_end)
+get_window_list (char *fmt, char *delim, struct sbuf *buffer,
+ int *mark_start, int *mark_end)
{
rp_window *w;
rp_window *other_window;
- char dbuf[10];
if (buffer == NULL) return;
@@ -582,7 +687,7 @@ get_window_list (char *delim, struct sbuf *buffer, int *mark_start, int *mark_en
w != rp_mapped_window_sentinel;
w = w->next)
{
- PRINT_DEBUG ("%d-%s\n", w->number, w->name);
+ PRINT_DEBUG ("%d-%s\n", w->number, window_name (w));
if (w == current_window())
*mark_start = strlen (sbuf_get (buffer));
@@ -592,17 +697,7 @@ get_window_list (char *delim, struct sbuf *buffer, int *mark_start, int *mark_en
if (!delim)
sbuf_concat (buffer, " ");
- sprintf (dbuf, "%d", w->number);
- sbuf_concat (buffer, dbuf);
-
- if (w == current_window())
- sbuf_concat (buffer, "*");
- else if (w == other_window)
- sbuf_concat (buffer, "+");
- else
- sbuf_concat (buffer, "-");
-
- sbuf_concat (buffer, w->name);
+ format_window_name (fmt, w, other_window, buffer);
/* A hack, pad the window with a space at the beginning and end
if there is no delimiter. */
diff --git a/src/list.h b/src/list.h
index 9d39df1..b8991e8 100644
--- a/src/list.h
+++ b/src/list.h
@@ -37,6 +37,8 @@ void give_window_focus (rp_window *win, rp_window *last_win);
void set_active_window (rp_window *win);
void goto_window (rp_window *win);
void set_current_window (rp_window *win);
+void update_window_position (rp_window *win);
+char *window_name (rp_window *win);
#if 0
void unhide_transient_for (rp_window *win);
@@ -61,6 +63,7 @@ void insert_into_list (rp_window *win, rp_window *sentinel);
void remove_from_list (rp_window *win);
void print_window_information (rp_window *win);
-void get_window_list (char *delim, struct sbuf *buffer, int *mark_start, int *mark_end);
+void get_window_list (char *fmt, char *delim, struct sbuf *buffer,
+ int *mark_start, int *mark_end);
#endif /* ! _RATPOISON_LIST_H */
diff --git a/src/main.c b/src/main.c
index 8d555aa..498029d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -62,9 +62,9 @@ screen_info *screens;
int num_screens;
Display *dpy;
-int ignore_badwindow = 0;
+struct rp_defaults defaults;
-static XFontStruct *font;
+int ignore_badwindow = 0;
char **myargv;
@@ -345,6 +345,46 @@ show_welcome_message ()
free (prefix);
}
+static void
+init_defaults ()
+{
+ defaults.win_pos = TOP_LEFT;
+ defaults.trans_pos = CENTER_CENTER;
+ defaults.maxsize_pos = CENTER_CENTER;
+
+ defaults.input_window_size = 200;
+ defaults.window_border_width = 1;
+ defaults.bar_x_padding = 0;
+ defaults.bar_y_padding = 0;
+ defaults.bar_location = TOP_RIGHT;
+ defaults.bar_timeout = 5;
+
+ defaults.frame_indicator_timeout = 1;
+
+ defaults.padding_left = 0;
+ defaults.padding_right = 0;
+ defaults.padding_top = 0;
+ defaults.padding_bottom = 0;
+
+ defaults.font = XLoadQueryFont (dpy, "9x15bold");
+ if (defaults.font == NULL)
+ {
+ fprintf (stderr, "ratpoison: Cannot load font %s.\n", "9x15bold");
+ exit (EXIT_FAILURE);
+ }
+
+ defaults.wait_for_key_cursor = 1;
+
+ defaults.window_fmt = strdup ("N-W");
+ if (defaults.window_fmt == NULL)
+ {
+ PRINT_ERROR ("Not enough memory\n");
+ exit (EXIT_FAILURE);
+ }
+
+ defaults.win_name = 0;
+}
+
int
main (int argc, char *argv[])
{
@@ -440,19 +480,13 @@ main (int argc, char *argv[])
set_sig_handler (SIGHUP, hup_handler);
/* Setup ratpoison's internal structures */
+ init_defaults();
init_numbers ();
init_window_list ();
init_frame_list ();
update_modifier_map ();
initialize_default_keybindings ();
- font = XLoadQueryFont (dpy, FONT);
- if (font == NULL)
- {
- fprintf (stderr, "ratpoison: Cannot load font %s.\n", FONT);
- exit (EXIT_FAILURE);
- }
-
num_screens = ScreenCount (dpy);
screens = (screen_info *)xmalloc (sizeof (screen_info) * num_screens);
@@ -483,8 +517,6 @@ init_rat_cursor (screen_info *s)
static void
init_screen (screen_info *s, int screen_num)
{
- XColor fg_color, bg_color,/* bold_color, */ junk;
-
/* Select on some events on the root window, if this fails, then
there is already a WM running and the X Error handler will catch
it, terminating ratpoison. */
@@ -497,29 +529,20 @@ init_screen (screen_info *s, int screen_num)
s->screen_num = screen_num;
s->root = RootWindow (dpy, 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))
- {
- fprintf (stderr, "ratpoison: Unknown color '%s'\n", FOREGROUND);
- }
-
- if (!XAllocNamedColor (dpy, s->def_cmap, BACKGROUND, &bg_color, &junk))
- {
- fprintf (stderr, "ratpoison: Unknown color '%s'\n", BACKGROUND);
- }
+ s->fg_color = BlackPixel (dpy, s->screen_num);
+ s->bg_color = WhitePixel (dpy, s->screen_num);
/* Setup the GC for drawing the font. */
- gv.foreground = fg_color.pixel;
- gv.background = bg_color.pixel;
+ gv.foreground = s->fg_color;
+ gv.background = s->bg_color;
gv.function = GXcopy;
gv.line_width = 1;
gv.subwindow_mode = IncludeInferiors;
- gv.font = font->fid;
+ gv.font = defaults.font->fid;
s->normal_gc = XCreateGC(dpy, s->root,
GCForeground | GCBackground | GCFunction
| GCLineWidth | GCSubwindowMode | GCFont,
@@ -528,28 +551,28 @@ init_screen (screen_info *s, int screen_num)
/* Create the program bar window. */
s->bar_is_raised = 0;
s->bar_window = XCreateSimpleWindow (dpy, s->root, 0, 0,
- 1, 1, 1, fg_color.pixel, bg_color.pixel);
+ 1, 1, 1, s->fg_color, s->bg_color);
XSelectInput (dpy, s->bar_window, StructureNotifyMask);
/* Setup the window that will recieve all keystrokes once the prefix
key has been pressed. */
- s->key_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, 0, WhitePixel (dpy, 0), BlackPixel (dpy, 0));
+ s->key_window = XCreateSimpleWindow (dpy, s->root, 0, 0, 1, 1, 0, WhitePixel (dpy, s->screen_num), BlackPixel (dpy, s->screen_num));
XSelectInput (dpy, s->key_window, KeyPressMask );
XMapWindow (dpy, s->key_window);
/* Create the input window. */
s->input_window = XCreateSimpleWindow (dpy, s->root, 0, 0,
- 1, 1, 1, fg_color.pixel, bg_color.pixel);
+ 1, 1, 1, s->fg_color, s->bg_color);
XSelectInput (dpy, s->input_window, KeyPressMask );
/* Create the frame indicator window */
s->frame_window = XCreateSimpleWindow (dpy, s->root, 1, 1, 1, 1, 1,
- fg_color.pixel, bg_color.pixel);
+ s->fg_color, s->bg_color);
XSelectInput (dpy, s->frame_window, KeyPressMask );
/* Create the help window */
s->help_window = XCreateSimpleWindow (dpy, s->root, 0, 0, s->root_attr.width,
- s->root_attr.height, 1, fg_color.pixel, bg_color.pixel);
+ s->root_attr.height, 1, s->fg_color, s->bg_color);
XSelectInput (dpy, s->help_window, KeyPressMask);
XSync (dpy, 0);
@@ -589,7 +612,7 @@ clean_up ()
XFreeGC (dpy, screens[i].normal_gc);
}
- XFreeFont (dpy, font);
+ XFreeFont (dpy, defaults.font);
XSetInputFocus (dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XCloseDisplay (dpy);
diff --git a/src/manage.c b/src/manage.c
index 47e5574..60f7971 100644
--- a/src/manage.c
+++ b/src/manage.c
@@ -84,8 +84,8 @@ update_normal_hints (rp_window *win)
}
-char *
-get_window_name (Window w)
+static char *
+get_wmname (Window w)
{
char *name;
XTextProperty text;
@@ -107,19 +107,85 @@ get_window_name (Window w)
if (list_len > 0)
{
name = xmalloc (strlen (name_list[0]) + 1);
-
strcpy (name, name_list[0]);
-
- /* Its our responsibility to free this. */
- XFreeStringList (name_list);
-
- return name;
+ }
+ else
+ {
+ name = NULL;
}
/* Its our responsibility to free this. */
XFreeStringList (name_list);
- return NULL;
+ return name;
+}
+
+static XClassHint *
+get_class_hints (Window w)
+{
+ XClassHint *class;
+
+ class = XAllocClassHint();
+
+ if (class == NULL)
+ {
+ PRINT_ERROR ("Not enough memory for WM_CLASS structure.\n");
+ exit (EXIT_FAILURE);
+ }
+
+ XGetClassHint (dpy, w, class);
+
+ return class;
+}
+
+static char *
+get_res_name (Window w)
+{
+ XClassHint *class;
+ char *name;
+
+ class = get_class_hints (w);
+
+ if (class->res_name)
+ {
+ name = (char *)xmalloc (strlen (class->res_name) + 1);
+ strcpy (name, class->res_name);
+ }
+ else
+ {
+ name = NULL;
+ }
+
+ XFree (class->res_name);
+ XFree (class->res_class);
+ XFree (class);
+
+ return name;
+}
+
+static char *
+get_res_class (Window w)
+{
+ XClassHint *class;
+ char *name;
+
+ class = get_class_hints (w);
+
+ if (class->res_class)
+ {
+ name = (char *)xmalloc (strlen (class->res_class) + 1);
+ strcpy (name, class->res_class);
+ }
+ else
+ {
+ name = NULL;
+ }
+
+ XFree (class->res_name);
+ XFree (class->res_class);
+ XFree (class);
+
+ return name;
}
/* Reget the WM_NAME property for the window and update its name. */
@@ -127,24 +193,30 @@ int
update_window_name (rp_window *win)
{
char *newstr;
- char *loc;
/* Don't overwrite the window name if the user specified one. */
- if (win->named) return 0;
+/* if (win->named) return 0; */
+
+ newstr = get_wmname (win->w);
+ if (newstr != NULL)
+ {
+ free (win->wm_name);
+ win->wm_name = newstr;
+ }
- newstr = get_window_name (win->w);
+ newstr = get_res_class (win->w);
if (newstr != NULL)
{
- free (win->name);
- win->name = newstr;
+ free (win->res_class);
+ win->res_class = newstr;
}
- /* A bit of a hack. If there's a : in the string, crop the
- string off there. This is mostly brought on by netscape's
- disgusting tendency to put its current URL in the WMName!!
- arg! */
- loc = strchr (win->name, ':');
- if (loc) loc[0] = '\0';
+ newstr = get_res_name (win->w);
+ if (newstr != NULL)
+ {
+ free (win->res_name);
+ win->res_name = newstr;
+ }
return 1;
}
@@ -190,6 +262,8 @@ update_window_information (rp_window *win)
/* Transient status */
win->transient = XGetTransientForHint (dpy, win->w, &win->transient_for);
+
+ update_window_position (win);
}
void
@@ -261,7 +335,7 @@ unmanaged_window (Window w)
for (i = 0; unmanaged_window_list[i]; i++)
{
- wname = get_window_name (w);
+ wname = get_wmname (w);
if (!wname)
return 0;
if (!strcmp (unmanaged_window_list[i], wname))
@@ -289,6 +363,53 @@ set_state (rp_window *win, int state)
PropModeReplace, (unsigned char *)data, 2);
}
+static void
+move_window (rp_window *win)
+{
+ if (win->frame == NULL)
+ return;
+
+ /* X coord. */
+ switch (win->position)
+ {
+ case TOP_LEFT:
+ case CENTER_LEFT:
+ case BOTTOM_LEFT:
+ win->x = win->frame->x;
+ break;
+ case TOP_CENTER:
+ case BOTTOM_CENTER:
+ case CENTER_CENTER:
+ win->x = win->frame->x + (win->frame->width - win->border * 2) / 2 - win->width / 2;
+ break;
+ case TOP_RIGHT:
+ case CENTER_RIGHT:
+ case BOTTOM_RIGHT:
+ win->x = win->frame->x + win->frame->width - win->width - win->border;
+ break;
+ }
+
+ /* Y coord. */
+ switch (win->position)
+ {
+ case TOP_LEFT:
+ case TOP_CENTER:
+ case TOP_RIGHT:
+ win->y = win->frame->y;
+ break;
+ case CENTER_LEFT:
+ case CENTER_CENTER:
+ case CENTER_RIGHT:
+ win->y = win->frame->y + (win->frame->height - win->border * 2) / 2 - win->height / 2;
+ break;
+ case BOTTOM_LEFT:
+ case BOTTOM_CENTER:
+ case BOTTOM_RIGHT:
+ win->y = win->frame->y + win->frame->height - win->height - win->border;
+ break;
+ }
+}
+
/* Set a transient window's x,y,width,height fields to maximize the
window. */
static void
@@ -297,8 +418,12 @@ maximize_transient (rp_window *win)
rp_window_frame *frame;
int maxx, maxy;
+ /* We can't maximize a window if it has no frame. */
+ if (win->frame == NULL)
+ return;
+
/* Set the window's border */
- win->border = WINDOW_BORDER_WIDTH;
+ win->border = defaults.window_border_width;
frame = win->frame;
@@ -336,22 +461,6 @@ maximize_transient (rp_window *win)
PRINT_DEBUG ("maxsize: %d %d\n", maxx, maxy);
- /* Fit the window inside its frame (if it has one) */
- if (frame)
- {
- win->x = frame->x - win->width / 2
- + (frame->width - win->border * 2) / 2;
- win->y = frame->y - win->height / 2
- + (frame->height - win->border * 2) / 2;
- }
- else
- {
- win->x = PADDING_LEFT - win->width / 2
- + (win->scr->root_attr.width - PADDING_LEFT - PADDING_RIGHT - win->border * 2) / 2;
- win->y = PADDING_TOP - win->height / 2
- + (win->scr->root_attr.height - PADDING_TOP - PADDING_BOTTOM - win->border * 2) / 2;
- }
-
win->width = maxx;
win->height = maxy;
}
@@ -363,11 +472,13 @@ maximize_normal (rp_window *win)
{
rp_window_frame *frame;
int maxx, maxy;
- int off_x = 0;
- int off_y = 0;
+
+ /* We can't maximize a window if it has no frame. */
+ if (win->frame == NULL)
+ return;
/* Set the window's border */
- win->border = WINDOW_BORDER_WIDTH;
+ win->border = defaults.window_border_width;
frame = win->frame;
@@ -379,10 +490,8 @@ maximize_normal (rp_window *win)
}
else
{
- maxx = win->scr->root_attr.width
- - PADDING_LEFT - PADDING_RIGHT - win->border * 2;
- maxy = win->scr->root_attr.height
- - PADDING_TOP - PADDING_BOTTOM - win->border * 2;
+ maxx = frame->width - win->border * 2;
+ maxy = frame->height - win->border * 2;
}
/* Fit the window inside its frame (if it has one) */
@@ -416,26 +525,6 @@ maximize_normal (rp_window *win)
}
PRINT_DEBUG ("maxsize: %d %d\n", maxx, maxy);
-
-#ifdef MAXSIZE_WINDOWS_ARE_TRANSIENTS
- if (win->hints->flags & PMaxSize && frame)
- {
- off_x = (frame->width - win->border * 2) / 2 - maxx / 2;
- off_y = (frame->height - win->border * 2) / 2 - maxy / 2;
- }
-#endif
-
- /* Fit the window inside its frame (if it has one) */
- if (frame)
- {
- win->x = frame->x + off_x;
- win->y = frame->y + off_y;
- }
- else
- {
- win->x = PADDING_LEFT + off_x;
- win->y = PADDING_TOP + off_y;
- }
win->width = maxx;
win->height = maxy;
@@ -459,6 +548,9 @@ maximize (rp_window *win)
maximize_normal (win);
}
+ /* Reposition the window. */
+ move_window (win);
+
/* Actually do the maximizing */
XMoveResizeWindow (dpy, win->w, win->x, win->y, win->width, win->height);
XSetWindowBorderWidth (dpy, win->w, win->border);
@@ -475,8 +567,20 @@ force_maximize (rp_window *win)
maximize_normal(win);
- /* Actually do the maximizing */
- XMoveResizeWindow (dpy, win->w, win->x, win->y, win->width+1, win->height+1);
+ /* Reposition the window. */
+ move_window (win);
+
+ if (win->hints->flags & PResizeInc)
+ {
+ XMoveResizeWindow (dpy, win->w, win->x, win->y,
+ win->width + win->hints->width_inc,
+ win->height + win->hints->height_inc);
+ }
+ else
+ {
+ XResizeWindow (dpy, win->w, win->width + 1, win->height + 1);
+ }
+
XMoveResizeWindow (dpy, win->w, win->x, win->y, win->width, win->height);
XSetWindowBorderWidth (dpy, win->w, win->border);
XSync (dpy, False);
@@ -486,7 +590,7 @@ force_maximize (rp_window *win)
void
map_window (rp_window *win)
{
- PRINT_DEBUG ("Mapping the unmapped window %s\n", win->name);
+ PRINT_DEBUG ("Mapping the unmapped window %s\n", window_name (win));
/* Fill in the necessary data about the window */
update_window_information (win);
@@ -512,10 +616,10 @@ map_window (rp_window *win)
{
if (win->transient)
marked_message_printf (0, 0, MESSAGE_MAP_TRANSIENT,
- win->number, win->name);
+ win->number, window_name (win));
else
marked_message_printf (0, 0, MESSAGE_MAP_WINDOW,
- win->number, win->name);
+ win->number, window_name (win));
}
}
@@ -570,7 +674,7 @@ withdraw_window (rp_window *win)
{
if (win == NULL) return;
- PRINT_DEBUG ("withdraw_window on '%s'\n", win->name);
+ PRINT_DEBUG ("withdraw_window on '%s'\n", window_name (win));
/* Give back the window number. the window will get another one,
if it is remapped. */
diff --git a/src/messages.h b/src/messages.h
index 1d8a94b..fd56dc4 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -24,24 +24,25 @@
#include "config.h"
-#define MESSAGE_NO_OTHER_WINDOW " No other window "
-#define MESSAGE_NO_OTHER_FRAME " No other frame "
-#define MESSAGE_NO_MANAGED_WINDOWS " No managed windows "
-#define MESSAGE_UNKNOWN_COMMAND ": unknown command '%s' "
-#define MESSAGE_WINDOW_INFORMATION " This is window %d (%s) "
+#define MESSAGE_NO_OTHER_WINDOW " No other window "
+#define MESSAGE_NO_OTHER_FRAME " No other frame "
+#define MESSAGE_NO_MANAGED_WINDOWS " No managed windows "
+#define MESSAGE_UNKNOWN_COMMAND ": unknown command '%s' "
+#define MESSAGE_WINDOW_INFORMATION " This is window %d (%s) "
#define MESSAGE_RAISE_TRANSIENT " Raise request from transient window %d (%s) "
-#define MESSAGE_RAISE_WINDOW " Raise request from window %d (%s) "
-#define MESSAGE_MAP_TRANSIENT " New transient window %d (%s) "
-#define MESSAGE_MAP_WINDOW " New window %d (%s) "
+#define MESSAGE_RAISE_WINDOW " Raise request from window %d (%s) "
+#define MESSAGE_MAP_TRANSIENT " New transient window %d (%s) "
+#define MESSAGE_MAP_WINDOW " New window %d (%s) "
#define MESSAGE_PROMPT_SWITCH_TO_WINDOW " Switch to window: "
-#define MESSAGE_PROMPT_NEW_WINDOW_NAME " Set window's title to: "
-#define MESSAGE_PROMPT_SHELL_COMMAND "/bin/sh -c "
-#define MESSAGE_PROMPT_COMMAND ":"
-#define MESSAGE_PROMPT_SWITCH_WM " Switch to wm: "
-#define MESSAGE_PROMPT_XTERM_COMMAND MESSAGE_PROMPT_SHELL_COMMAND TERM_PROG " -e "
+#define MESSAGE_PROMPT_NEW_WINDOW_NAME " Set window's title to: "
+#define MESSAGE_PROMPT_SHELL_COMMAND "/bin/sh -c "
+#define MESSAGE_PROMPT_COMMAND ":"
+#define MESSAGE_PROMPT_SWITCH_WM " Switch to wm: "
+#define MESSAGE_PROMPT_XTERM_COMMAND MESSAGE_PROMPT_SHELL_COMMAND TERM_PROG " -e "
-#define MESSAGE_WELCOME " Welcome to ratpoison! Hit `%s %s' for help. "
+#define MESSAGE_WELCOME " Welcome to ratpoison! Hit `%s %s' for help. "
+#define MESSAGE_FRAME_STRING "Current Frame"
#endif /* ! _RATPOISON_MESSAGES_H */
diff --git a/src/split.c b/src/split.c
index 7820a36..b915714 100644
--- a/src/split.c
+++ b/src/split.c
@@ -68,12 +68,12 @@ delete_frame_from_list (rp_window_frame *frame)
static void
maximize_frame (rp_window_frame *frame)
{
- frame->x = PADDING_LEFT;
- frame->y = PADDING_TOP;
+ frame->x = defaults.padding_left;
+ frame->y = defaults.padding_top;
/* FIXME: what about multiple screens? */
- frame->width = DisplayWidth (dpy, 0) - PADDING_RIGHT - PADDING_LEFT;
- frame->height = DisplayHeight (dpy, 0) - PADDING_BOTTOM - PADDING_TOP;
+ frame->width = DisplayWidth (dpy, 0) - defaults.padding_right - defaults.padding_left;
+ frame->height = DisplayHeight (dpy, 0) - defaults.padding_bottom - defaults.padding_top;
}
/* Create a full screen frame */
@@ -560,8 +560,8 @@ show_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);
+ width = defaults.bar_x_padding * 2 + XTextWidth (defaults.font, MESSAGE_FRAME_STRING, strlen (MESSAGE_FRAME_STRING));
+ height = (FONT_HEIGHT (defaults.font) + defaults.bar_y_padding * 2);
XMoveResizeWindow (dpy, current_screen()->frame_window,
rp_current_frame->x + rp_current_frame->width / 2 - width / 2,
@@ -572,9 +572,9 @@ show_frame_indicator ()
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));
+ defaults.bar_x_padding,
+ defaults.bar_y_padding + defaults.font->max_bounds.ascent,
+ MESSAGE_FRAME_STRING, strlen (MESSAGE_FRAME_STRING));
- alarm (FRAME_INDICATOR_TIMEOUT);
+ alarm (defaults.frame_indicator_timeout);
}