diff options
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/actions.c | 104 | ||||
-rw-r--r-- | src/actions.h | 2 | ||||
-rw-r--r-- | src/data.h | 7 | ||||
-rw-r--r-- | src/events.c | 3 | ||||
-rw-r--r-- | src/globals.c | 15 | ||||
-rw-r--r-- | src/globals.h | 6 | ||||
-rw-r--r-- | src/group.c | 12 | ||||
-rw-r--r-- | src/group.h | 2 | ||||
-rw-r--r-- | src/hook.c | 84 | ||||
-rw-r--r-- | src/hook.h | 29 | ||||
-rw-r--r-- | src/ratpoison.h | 1 | ||||
-rw-r--r-- | src/split.c | 4 | ||||
-rw-r--r-- | src/window.c | 3 |
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 (); @@ -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 |