summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am4
-rw-r--r--src/actions.c104
-rw-r--r--src/actions.h2
-rw-r--r--src/data.h7
-rw-r--r--src/events.c3
-rw-r--r--src/globals.c15
-rw-r--r--src/globals.h6
-rw-r--r--src/group.c12
-rw-r--r--src/group.h2
-rw-r--r--src/hook.c84
-rw-r--r--src/hook.h29
-rw-r--r--src/ratpoison.h1
-rw-r--r--src/split.c4
-rw-r--r--src/window.c3
14 files changed, 270 insertions, 6 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 953e256..3cd61b6 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.18 2003/05/27 07:51:06 sabetts Exp $
+## $Id: Makefile.am,v 1.19 2003/07/17 05:41:41 sabetts Exp $
bin_PROGRAMS = ratpoison
@@ -46,6 +46,8 @@ ratpoison_SOURCES = actions.c \
group.c \
history.h \
history.c \
+ hook.c \
+ hook.h \
input.c \
input.h \
linkedlist.h \
diff --git a/src/actions.c b/src/actions.c
index d51f326..34acf40 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -106,6 +106,8 @@ static user_command user_commands[] =
{"groups", cmd_groups, arg_VOID},
{"gmove", cmd_gmove, arg_VOID},
{"gmerge", cmd_gmerge, arg_VOID},
+ {"addhook", cmd_addhook, arg_STRING},
+ {"remhook", cmd_remhook, arg_STRING},
/* Commands to set default behavior. */
{"defbargravity", cmd_defbargravity, arg_STRING},
@@ -1343,7 +1345,13 @@ cmd_windows (int interactive, char *data)
if (interactive)
{
s = current_screen ();
- if (!hide_bar (s)) show_bar (s);
+ /* This is a yukky hack. If the bar already hidden then show the
+ bar. This handles the case when msgwait is 0 (the bar sticks)
+ and the user uses this command to toggle the bar on and
+ off. OR the timeout is >0 then show the bar. Which means,
+ always show the bar if msgwait is >0 which fixes the case
+ when a command in the prefix hook displays the bar. */
+ if (!hide_bar (s) || defaults.bar_timeout > 0) show_bar (s);
return NULL;
}
@@ -3424,21 +3432,21 @@ cmd_defwinliststyle (int interactive, char *data)
char *
cmd_gnext (int interactive, char *data)
{
- rp_current_group = group_next_group ();
+ set_current_group (group_next_group ());
return NULL;
}
char *
cmd_gprev (int interactive, char *data)
{
- rp_current_group = group_prev_group ();
+ set_current_group (group_prev_group ());
return NULL;
}
char *
cmd_gnew (int interactive, char *data)
{
- rp_current_group = group_add_new_group (data);
+ set_current_group (group_add_new_group (data));
return NULL;
}
@@ -3521,7 +3529,7 @@ cmd_gselect (int interactive, char *data)
g = find_group (str);
if (g)
- rp_current_group = g;
+ set_current_group (g);
else
return cmd_groups (interactive, NULL);
@@ -3646,3 +3654,89 @@ cmd_gmerge (int interactive, char *data)
return NULL;
}
+
+char *
+cmd_addhook (int interactive, char *data)
+{
+ char *dup;
+ char *token;
+ struct list_head *hook;
+ struct sbuf *cmd;
+
+ if (data == NULL)
+ {
+ message (" addhook: two arguments required ");
+ return NULL;
+ }
+
+ dup = xstrdup (data);
+ token = strtok (dup, " ");
+
+ hook = hook_lookup (token);
+ if (hook == NULL)
+ {
+ marked_message_printf (0, 0, " addhook: unknown hook \"%s\"", token);
+ free (dup);
+ return NULL;
+ }
+
+ token = strtok (NULL, "\0");
+
+ if (token == NULL)
+ {
+ message (" addhook: two arguments required ");
+ free (dup);
+ return NULL;
+ }
+
+ /* Add the command to the hook */
+ cmd = sbuf_new (0);
+ sbuf_copy (cmd, token);
+ hook_add (hook, cmd);
+
+ free (dup);
+ return NULL;
+}
+
+char *
+cmd_remhook (int interactive, char *data)
+{
+ char *dup;
+ char *token;
+ struct list_head *hook;
+ struct sbuf *cmd;
+
+ if (data == NULL)
+ {
+ message (" remhook: two arguments required ");
+ return NULL;
+ }
+
+ dup = xstrdup (data);
+ token = strtok (dup, " ");
+
+ hook = hook_lookup (token);
+ if (hook == NULL)
+ {
+ marked_message_printf (0, 0, " addhook: unknown hook \"%s\"", token);
+ free (dup);
+ return NULL;
+ }
+
+ token = strtok (NULL, "\0");
+
+ if (token == NULL)
+ {
+ message (" addhook: two arguments required ");
+ free (dup);
+ return NULL;
+ }
+
+ /* Add the command to the hook */
+ cmd = sbuf_new (0);
+ sbuf_copy (cmd, token);
+ hook_remove (hook, cmd);
+
+ free (dup);
+ return NULL;
+}
diff --git a/src/actions.h b/src/actions.h
index 4629d5a..25d4046 100644
--- a/src/actions.h
+++ b/src/actions.h
@@ -132,6 +132,8 @@ char *cmd_verbexec (int interactive, char *data);
char *cmd_version (int interactive, char *data);
char *cmd_warp(int interactive, char *data);
char *cmd_windows (int interactive, char *data);
+char *cmd_addhook (int interactive, char *data);
+char *cmd_remhook (int interactive, char *data);
void initialize_default_keybindings (void);
void free_keybindings ();
diff --git a/src/data.h b/src/data.h
index 09f9eba..9fa2f90 100644
--- a/src/data.h
+++ b/src/data.h
@@ -296,4 +296,11 @@ struct rp_input_line
Atom selection;
};
+/* The hook dictionary. */
+struct rp_hook_db_entry
+{
+ char *name;
+ struct list_head *hook;
+};
+
#endif /* _RATPOISON_DATA_H */
diff --git a/src/events.c b/src/events.c
index 5cbe73a..2ce6409 100644
--- a/src/events.c
+++ b/src/events.c
@@ -394,6 +394,9 @@ handle_key (rp_screen *s)
rat_grabbed = 1;
}
+ /* Call the prefix hook. */
+ hook_run (&rp_prefix_hook);
+
read_key (&keysym, &mod, NULL, 0);
XSetInputFocus (dpy, fwin, revert, CurrentTime);
diff --git a/src/globals.c b/src/globals.c
index 319ac91..2cc7d78 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -66,3 +66,18 @@ int rp_honour_transient_map = 1;
int rp_honour_normal_map = 1;
char *rp_error_msg = NULL;
+
+/* The hook dictionary globals. */
+
+LIST_HEAD (rp_prefix_hook);
+LIST_HEAD (rp_switch_win_hook);
+LIST_HEAD (rp_switch_frame_hook);
+LIST_HEAD (rp_switch_group_hook);
+
+struct rp_hook_db_entry rp_hook_db[]=
+ {{"prefix", &rp_prefix_hook},
+ {"switchwin", &rp_switch_win_hook},
+ {"switchframe", &rp_switch_frame_hook},
+ {"switchgroup", &rp_switch_group_hook},
+ {NULL, NULL}};
+
diff --git a/src/globals.h b/src/globals.h
index cca5f27..7c25741 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -125,5 +125,11 @@ extern char *rp_error_msg;
/* Number sets for windows. */
extern struct numset *rp_window_numset;
+extern struct list_head rp_prefix_hook;
+extern struct list_head rp_switch_win_hook;
+extern struct list_head rp_switch_frame_hook;
+extern struct list_head rp_switch_group_hook;
+
+extern struct rp_hook_db_entry rp_hook_db[];
#endif
diff --git a/src/group.c b/src/group.c
index 38b0fd3..98923df 100644
--- a/src/group.c
+++ b/src/group.c
@@ -464,3 +464,15 @@ groups_merge (rp_group *from, rp_group *to)
group_insert_window (&to->mapped_windows, cur);
}
}
+
+void
+set_current_group (rp_group *g)
+{
+ if (rp_current_group == g || g == NULL)
+ return;
+
+ rp_current_group = g;
+
+ /* Call the switch group hook. */
+ hook_run (&rp_switch_group_hook);
+}
diff --git a/src/group.h b/src/group.h
index 87b54af..4104d6e 100644
--- a/src/group.h
+++ b/src/group.h
@@ -36,4 +36,6 @@ rp_window_elem *group_find_window_by_number (rp_group *g, int num);
void group_move_window (rp_group *to, rp_window *win);
void groups_merge (rp_group *from, rp_group *to);
+void set_current_group (rp_group *g);
+
#endif
diff --git a/src/hook.c b/src/hook.c
new file mode 100644
index 0000000..830099d
--- /dev/null
+++ b/src/hook.c
@@ -0,0 +1,84 @@
+/* Copyright (C) 2000, 2001, 2002, 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
+ */
+
+/* A hook is simply a list of strings that get passed to command() in
+ sequence. */
+
+#include "ratpoison.h"
+
+void
+hook_add (struct list_head *hook, struct sbuf *s)
+{
+ struct sbuf *cur;
+
+ /* Check if it's in the list already. */
+ list_for_each_entry (cur, hook, node)
+ {
+ if (!strcmp (sbuf_get (cur), sbuf_get (s)))
+ return;
+ }
+
+ /* It's not in the list, so add it. */
+ list_add_tail (&s->node, hook);
+}
+
+void
+hook_remove (struct list_head *hook, struct sbuf *s)
+{
+ struct list_head *tmp, *iter;
+ struct sbuf *cur;
+
+ /* If it's in the list, delete it. */
+ list_for_each_safe_entry (cur, iter, tmp, hook, node)
+ {
+ if (!strcmp (sbuf_get (cur), sbuf_get (s)))
+ {
+ list_del (&cur->node);
+ sbuf_free (cur);
+ }
+ }
+}
+
+void
+hook_run (struct list_head *hook)
+{
+ struct sbuf *cur;
+
+ list_for_each_entry (cur, hook, node)
+ {
+ command (1, sbuf_get (cur));
+ }
+}
+
+struct list_head *
+hook_lookup (char *s)
+{
+ struct rp_hook_db_entry *entry;
+
+ for (entry = rp_hook_db; entry->name; entry++)
+ {
+ if (!strcmp (s, entry->name))
+ {
+ return entry->hook;
+ }
+ }
+
+ return NULL;
+}
diff --git a/src/hook.h b/src/hook.h
new file mode 100644
index 0000000..60f37ae
--- /dev/null
+++ b/src/hook.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2000, 2001, 2002, 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 HOOKS_H
+#define HOOKS_H
+
+void hook_run (struct list_head *hook);
+void hook_remove (struct list_head *hook, struct sbuf *s);
+void hook_add (struct list_head *hook, struct sbuf *s);
+struct list_head *hook_lookup (char *s);
+
+#endif
diff --git a/src/ratpoison.h b/src/ratpoison.h
index b643aab..34f528e 100644
--- a/src/ratpoison.h
+++ b/src/ratpoison.h
@@ -75,6 +75,7 @@ extern XGCValues gv;
#include "editor.h"
#include "history.h"
#include "completions.h"
+#include "hook.h"
void clean_up ();
rp_screen *find_screen (Window w);
diff --git a/src/split.c b/src/split.c
index 854139a..c0405af 100644
--- a/src/split.c
+++ b/src/split.c
@@ -849,6 +849,10 @@ set_active_frame (rp_frame *frame)
|| s != old_s)
{
show_frame_indicator();
+
+ /* run the frame switch hook. We call it in here because this is
+ when a frame switch ACTUALLY (for sure) happens. */
+ hook_run (&rp_switch_frame_hook);
}
/* If the frame has no window to give focus to, give the key window
diff --git a/src/window.c b/src/window.c
index 416b63f..70b9e30 100644
--- a/src/window.c
+++ b/src/window.c
@@ -488,6 +488,9 @@ set_active_window (rp_window *win)
update_window_names (win->scr);
XSync (dpy, False);
+
+ /* Call the switch window hook */
+ hook_run (&rp_switch_win_hook);
}
/* Go to the window, switching frames if the window is already in a