summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ChangeLog15
-rw-r--r--src/Makefile.am2
-rw-r--r--src/bar.c7
-rw-r--r--src/bar.h1
-rw-r--r--src/conf.h16
-rw-r--r--src/data.h16
-rw-r--r--src/events.c162
-rw-r--r--src/list.c51
-rw-r--r--src/list.h2
-rw-r--r--src/main.c12
-rw-r--r--src/manage.c26
-rw-r--r--src/ratpoison.h3
12 files changed, 97 insertions, 216 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4a60d19..ab37eac 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,18 @@
+2000-10-17 shawn <sabetts@vcn.bc.ca>
+
+ * manage.c (scanwins): Now only maps visible windows
+
+ * conf.h: Removed keystroke related defines
+
+ * actions.c: Moved all key activated functions here. Added
+ key_actions array.
+
+ * events.c (unmap_notify): now properly unmaps windows
+
+ * data.h: added ignore_badwindow
+
+ * main.c (handler): added ability to ignore BadWindow errors
+
2000-10-15 shawn <sabetts@vcn.bc.ca>
* main.c, data.h, events.c: Added ability to kill and hup running
diff --git a/src/Makefile.am b/src/Makefile.am
index d3af0be..0cc011e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,4 +2,4 @@ bin_PROGRAMS = ratpoison
ratpoison_SOURCES = bar.c bar.h conf.h data.h events.c events.h \
input.c input.h list.c list.h main.c manage.c manage.h number.c \
-number.h ratpoison.h
+number.h ratpoison.h actions.h actions.c
diff --git a/src/bar.c b/src/bar.c
index d06dcc8..5ec2ab2 100644
--- a/src/bar.c
+++ b/src/bar.c
@@ -59,13 +59,6 @@ show_bar (screen_info *s)
return 0;
}
-/* Toggle the display of the program bar */
-void
-toggle_bar (screen_info *s)
-{
- if (!hide_bar (s)) show_bar (s);
-}
-
static int
calc_bar_width (XFontStruct *font)
{
diff --git a/src/bar.h b/src/bar.h
index 6083762..383bcdf 100644
--- a/src/bar.h
+++ b/src/bar.h
@@ -21,7 +21,6 @@
#define _BAR_H
void update_window_names (screen_info *s);
-void toggle_bar (screen_info *s);
int show_bar (screen_info *s);
int hide_bar (screen_info *s);
int bar_y (screen_info *s);
diff --git a/src/conf.h b/src/conf.h
index 8efee2e..395945c 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -17,22 +17,12 @@
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA */
+#include "data.h"
+#include "actions.h"
+
#define KEY_PREFIX 't'
#define MODIFIER_PREFIX ControlMask
-#define KEY_XTERM 'c'
-#define KEY_EMACS 'e'
-#define KEY_PREVWINDOW 'p'
-#define KEY_NEXTWINDOW 'n'
-#define KEY_LASTWINDOW 't' /* key to toggle between the current window and the last visitted one */
-#define KEY_TOGGLEBAR 'w' /* key to toggle the display of the program bar */
-#define KEY_DELETE 'k' /* delete a window SHIFT+key will Destroy the window */
-#define KEY_WINBYNAME '\'' /* key to jump to a window by name */
-#define KEY_RENAME 'a' /* key to rename a window. */
-
-#define TERM_PROG "xterm" /* command to boot an x term */
-#define EMACS_PROG "emacs" /* command to boot emacs */
-
#define BAR_FG_COLOR "Gray60"
#define BAR_BG_COLOR "Lightgreen"
#define BAR_BOLD_COLOR "Black" /* To indicate the current window */
diff --git a/src/data.h b/src/data.h
index 586074f..214a8c0 100644
--- a/src/data.h
+++ b/src/data.h
@@ -31,6 +31,7 @@
typedef struct rp_window rp_window;
typedef struct screen_info screen_info;
+typedef struct rp_action rp_action;
struct rp_window
{
@@ -56,6 +57,14 @@ struct screen_info
Colormap def_cmap;
};
+struct rp_action
+{
+ int key;
+ int state;
+ void *data; /* misc data to be passed to the function */
+ void (*func)(void *);
+};
+
extern rp_window *rp_window_head, *rp_window_tail;
extern rp_window *rp_current_window;
extern screen_info *screens;
@@ -72,9 +81,10 @@ extern Atom wm_delete;
extern Atom wm_take_focus;
extern Atom wm_colormaps;
-/* Set to 1 to indicate that the WM should exit at it's earliest
- convenience. */
-extern int exit_signal;
+/* When unmapping or deleting windows, it is sometimes helpful to
+ ignore a bad window when attempting to clean the window up. This
+ does just that when set to 1 */
+extern int ignore_badwindow;
/* Arguments passed to ratpoison. */
extern char **myargv;
diff --git a/src/events.c b/src/events.c
index f40aed7..d7a2c1d 100644
--- a/src/events.c
+++ b/src/events.c
@@ -19,39 +19,17 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
-#include <X11/keysymdef.h>
+#include <X11/keysym.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <sys/wait.h>
#include "ratpoison.h"
extern Display *dpy;
void
-spawn(char *prog)
-{
- /*
- * ugly dance to avoid leaving zombies. Could use SIGCHLD,
- * but it's not very portable.
- */
- if (fork() == 0) {
- if (fork() == 0) {
- putenv(DisplayString(dpy));
- execlp(prog, prog, 0);
- fprintf (stderr, "exec %s ", prog);
- perror(" failed");
- exit(EXIT_FAILURE);
- }
- exit(0);
- }
- wait((int *) 0);
- PRINT_DEBUG ("spawned %s\n", prog);
-}
-
-void
new_window (XCreateWindowEvent *e)
{
rp_window *win;
@@ -81,11 +59,28 @@ unmap_notify (XEvent *ev)
if (s && win)
{
+ long data[2] = { WithdrawnState, None };
+
/* Give back the window number. the window will get another one,
if it in remapped. */
return_window_number (win->number);
win->number = -1;
win->state = STATE_UNMAPPED;
+
+ /* Update the state of the actual window */
+ XRemoveFromSaveSet (dpy, win->w);
+ XChangeProperty(dpy, win->w, wm_state, wm_state, 32,
+ PropModeReplace, (unsigned char *)data, 2);
+
+ ignore_badwindow = 1;
+ XSync(dpy, False);
+ ignore_badwindow = 0;
+
+ if (rp_current_window == win)
+ {
+ last_window (NULL);
+ }
+
update_window_names (s);
}
}
@@ -165,7 +160,7 @@ destroy_window (XDestroyWindowEvent *ev)
if (last_destroy_event && switch_window_pending)
{
- last_window ();
+ last_window (NULL);
switch_window_pending = 0;
}
}
@@ -200,7 +195,7 @@ configure_request (XConfigureRequestEvent *e)
}
else if (e->detail == Below && win == rp_current_window)
{
- last_window ();
+ last_window (NULL);
}
}
@@ -208,33 +203,6 @@ configure_request (XConfigureRequestEvent *e)
}
}
-void
-delete_window ()
-{
- XEvent ev;
- int status;
-
- if (rp_current_window == NULL) return;
-
- ev.xclient.type = ClientMessage;
- ev.xclient.window = rp_current_window->w;
- ev.xclient.message_type = wm_protocols;
- ev.xclient.format = 32;
- ev.xclient.data.l[0] = wm_delete;
- ev.xclient.data.l[1] = CurrentTime;
-
- status = XSendEvent(dpy, rp_current_window->w, False, 0, &ev);
- if (status == 0) fprintf(stderr, "ratpoison: delete window failed\n");
-}
-
-void
-kill_window ()
-{
- if (rp_current_window == NULL) return;
-
- XKillClient(dpy, rp_current_window->w);
-}
-
static void
client_msg (XClientMessageEvent *ev)
{
@@ -255,19 +223,9 @@ client_msg (XClientMessageEvent *ev)
}
static void
-goto_win_by_name (screen_info *s)
-{
- char winname[100];
-
- get_input (s, "Window: ", winname, 100);
- PRINT_DEBUG ("user entered: %s\n", winname);
-
- goto_window_name (winname);
-}
-
-static void
handle_key (screen_info *s)
{
+ const rp_action *i;
int revert;
Window fwin;
XEvent ev;
@@ -277,10 +235,29 @@ handle_key (screen_info *s)
XGetInputFocus (dpy, &fwin, &revert);
XSetInputFocus (dpy, s->key_window, RevertToPointerRoot, CurrentTime);
- XMaskEvent (dpy, KeyPressMask, &ev);
+
+ do
+ {
+ XMaskEvent (dpy, KeyPressMask, &ev);
+ keysym = XLookupKeysym((XKeyEvent *) &ev, 0);
+ } while (keysym == XK_Shift_L
+ || keysym == XK_Shift_R
+ || keysym == XK_Control_L
+ || keysym == XK_Control_R
+ || keysym == XK_Caps_Lock
+ || keysym == XK_Shift_Lock
+ || keysym == XK_Meta_L
+ || keysym == XK_Meta_R
+ || keysym == XK_Alt_L
+ || keysym == XK_Alt_R
+ || keysym == XK_Super_L
+ || keysym == XK_Super_R
+ || keysym == XK_Hyper_L
+ || keysym == XK_Hyper_R); /* ignore modifier keypresses. */
+
XSetInputFocus (dpy, fwin, revert, CurrentTime);
- if (XLookupKeysym((XKeyEvent *) &ev, 0) == KEY_PREFIX && !ev.xkey.state)
+ if (keysym == KEY_PREFIX && !ev.xkey.state)
{
/* Generate the prefix keystroke for the app */
ev.xkey.window = fwin;
@@ -290,54 +267,17 @@ handle_key (screen_info *s)
return;
}
- keysym = XLookupKeysym((XKeyEvent *) &ev, 0);
-
- if (keysym == KEY_TOGGLEBAR)
- {
- toggle_bar (s);
- return;
- }
-
- /* All functions tested for after this point hide the program bar. */
+ /* All functions hide the program bar. */
hide_bar (s);
- if (keysym >= '0' && keysym <= '9')
- {
- goto_window_number (XLookupKeysym((XKeyEvent *) &ev, 0) - '0');
- hide_bar (s);
- return;
- }
-
- switch (keysym)
+ for (i = key_actions; i->key != 0; i++)
{
- case KEY_XTERM:
- spawn (TERM_PROG);
- break;
- case KEY_EMACS:
- spawn (EMACS_PROG);
- break;
- case KEY_PREVWINDOW:
- prev_window ();
- break;
- case KEY_NEXTWINDOW:
- next_window ();
- break;
- case KEY_LASTWINDOW:
- last_window ();
- break;
- case KEY_WINBYNAME:
- goto_win_by_name (s);
- break;
- case KEY_RENAME:
- rename_current_window ();
- break;
- case KEY_DELETE:
- if (ev.xkey.state & ShiftMask) kill_window ();
- else delete_window ();
- break;
- default:
- PRINT_DEBUG ("Unknown key command '%c'\n", (char)keysym);
- break;
+ if (keysym == i->key)
+ if (i->state == -1 || ev.xkey.state == i->state)
+ {
+ (*i->func)(i->data);
+ break;
+ }
}
}
@@ -435,7 +375,7 @@ delegate_event (XEvent *ev)
break;
case KeyPress:
- PRINT_DEBUG ("KeyPress\n");
+ PRINT_DEBUG ("KeyPress %d %d\n", ev->xkey.keycode, ev->xkey.state);
key_press (ev);
break;
diff --git a/src/list.c b/src/list.c
index 0393923..c4737ce 100644
--- a/src/list.c
+++ b/src/list.c
@@ -112,36 +112,6 @@ init_window_list ()
rp_current_window = NULL;
}
-void
-next_window ()
-{
- if (rp_current_window != NULL)
- {
- rp_current_window = rp_current_window->next;
- if (rp_current_window == NULL)
- {
- rp_current_window = rp_window_head;
- }
- if (rp_current_window->state == STATE_UNMAPPED) next_window ();
- set_active_window (rp_current_window);
- }
-}
-
-void
-prev_window ()
-{
- if (rp_current_window != NULL)
- {
- set_current_window (rp_current_window->prev);
- if (rp_current_window == NULL)
- {
- rp_current_window = rp_window_tail;
- }
- if (rp_current_window->state == STATE_UNMAPPED) prev_window ();
- set_active_window (rp_current_window);
- }
-}
-
rp_window *
find_window_by_number (int n)
{
@@ -196,20 +166,6 @@ goto_window_name (char *name)
set_active_window (rp_current_window);
}
-void
-goto_window_number (int n)
-{
- rp_window *win;
-
- if ((win = find_window_by_number (n)) == NULL)
- {
- return;
- }
-
- rp_current_window = win;
- set_active_window (rp_current_window);
-}
-
rp_window *
find_last_accessed_window ()
{
@@ -240,13 +196,6 @@ find_last_accessed_window ()
}
void
-last_window ()
-{
- rp_current_window = find_last_accessed_window ();
- set_active_window (rp_current_window);
-}
-
-void
set_active_window (rp_window *rp_w)
{
static int counter = 1; /* increments every time this function
diff --git a/src/list.h b/src/list.h
index 170c2e2..15b1d98 100644
--- a/src/list.h
+++ b/src/list.h
@@ -32,4 +32,6 @@ void set_active_window (rp_window *rp_w);
void set_current_window (rp_window *win);
void goto_window_number (int n);
void goto_window_name (char *name);
+rp_window *find_last_accessed_window ();
+rp_window *find_window_by_number (int n);
#endif /* _LIST_H */
diff --git a/src/main.c b/src/main.c
index 253efe9..8ac4bd5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -45,8 +45,9 @@ Atom rp_kill;
screen_info *screens;
int num_screens;
Display *dpy;
-int exit_signal = 0; /* Set by the signal handler. if this
- is set, quit. */
+
+int ignore_badwindow = 0;
+
static XFontStruct *font;
char **myargv;
@@ -57,7 +58,7 @@ static struct option ratpoison_longopts[] = { {"help", no_argument, 0, 'h'},
{"restart", no_argument, 0, 'r'},
{"kill", no_argument, 0, 'k'},
{0, 0, 0, 0} };
-static char ratpoison_opts[] = "hv";
+static char ratpoison_opts[] = "hvrk";
void
sighandler ()
@@ -145,11 +146,12 @@ handler (Display *d, XErrorEvent *e)
exit(EXIT_FAILURE);
}
+ if (ignore_badwindow && e->error_code == BadWindow) return 0;
+
XGetErrorText (d, e->error_code, error_msg, sizeof (error_msg));
fprintf (stderr, "ratpoison: %s!\n", error_msg);
- return 0;
- /* exit (EXIT_FAILURE); */
+ exit (EXIT_FAILURE);
}
void
diff --git a/src/manage.c b/src/manage.c
index 592200a..9027b80 100644
--- a/src/manage.c
+++ b/src/manage.c
@@ -101,29 +101,6 @@ update_window_name (rp_window *win)
return 1;
}
-void
-rename_current_window ()
-{
- char winname[100];
-
- if (rp_current_window == NULL) return;
-
- get_input (rp_current_window->scr, "Name: ", winname, 100);
- PRINT_DEBUG ("user entered: %s\n", winname);
-
- free (rp_current_window->name);
- rp_current_window->name = malloc (sizeof (char) * strlen (winname) + 1);
- if (rp_current_window->name == NULL)
- {
- PRINT_ERROR ("Out of memory\n");
- exit (EXIT_FAILURE);
- }
- strcpy (rp_current_window->name, winname);
- rp_current_window->named = 1;
-
- /* Update the program bar. */
- update_window_names (rp_current_window->scr);
-}
void
manage (rp_window *win, screen_info *s)
@@ -170,7 +147,8 @@ scanwins(screen_info *s)
if (attr.override_redirect != True)
{
win = add_to_window_list (s, wins[i]);
- if (attr.map_state != IsUnmapped) manage (win, s);
+ PRINT_DEBUG ("map_state: %d\n", attr.map_state);
+ if (attr.map_state == IsViewable) manage (win, s);
}
}
XFree((void *) wins); /* cast is to shut stoopid compiler up */
diff --git a/src/ratpoison.h b/src/ratpoison.h
index 089fcb9..e5d0a35 100644
--- a/src/ratpoison.h
+++ b/src/ratpoison.h
@@ -24,6 +24,9 @@
# include <config.h>
#endif /* HAVE_CONFIG_H */
+#include <stdlib.h>
+#include <stdio.h>
+
/* Some error reporting macros */
#define PRE_PRINT_LOCATION fprintf (stderr, "%s:%s():%d: ", __FILE__, __FUNCTION__, __LINE__);
#define PRINT_ERROR(format, args...) \