context menu for urls

This commit is contained in:
Sascha Kruse 2012-12-19 15:56:15 +01:00
parent 9a662f2313
commit 42e49a7b34
5 changed files with 109 additions and 0 deletions

View File

@ -37,6 +37,11 @@ int startup_notification = False;
/* monitor to display notifications on */ /* monitor to display notifications on */
int monitor = 0; int monitor = 0;
/* path to dmenu */
char *dmenu = "/usr/bin/dmenu";
char *browser = "/usr/bin/firefox";
/* follow focus to different monitor and display notifications there? /* follow focus to different monitor and display notifications there?
* possible values: * possible values:
* FOLLOW_NONE * FOLLOW_NONE
@ -60,6 +65,9 @@ keyboard_shortcut close_all_ks = {.str = "none",
keyboard_shortcut history_ks = {.str = "none", keyboard_shortcut history_ks = {.str = "none",
.code = 0, .sym = NoSymbol,.is_valid = False}; /* ignore this */ .code = 0, .sym = NoSymbol,.is_valid = False}; /* ignore this */
keyboard_shortcut context_ks = {.str = "none",
.code = 0, .sym = NoSymbol,.is_valid = False}; /* ignore this */
rule_t default_rules[] = { rule_t default_rules[] = {
/* name can be any unique string. It is used to identify the rule in dunstrc to override it there */ /* name can be any unique string. It is used to identify the rule in dunstrc to override it there */

71
dunst.c
View File

@ -102,6 +102,7 @@ void hide_win(void);
void move_all_to_history(void); void move_all_to_history(void);
void print_version(void); void print_version(void);
str_array *extract_urls(const char *str); str_array *extract_urls(const char *str);
void context_menu(void);
void r_line_cache_init(r_line_cache *c); void r_line_cache_init(r_line_cache *c);
void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col, bool continues); void r_line_cache_append(r_line_cache *c, const char *s, ColorSet *col, bool continues);
@ -153,6 +154,57 @@ str_array *extract_urls( const char * to_match)
return urls; return urls;
} }
void context_menu(void) {
char *dmenu_input = NULL;
n_queue *iter = displayed;
while (iter) {
for (int i = 0; i < iter->n->urls->count; i++) {
dmenu_input = string_append(dmenu_input,
(iter->n->urls->strs)[i], "\n");
}
iter = iter->next;
}
int child_io[2];
int parent_io[2];
pipe(child_io);
pipe(parent_io);
int pid = fork();
if (pid == 0) {
close(child_io[1]);
close(parent_io[0]);
close(0);
dup(child_io[0]);
close(1);
dup(parent_io[1]);
execlp(dmenu, dmenu, (char *) NULL);
} else {
close(child_io[0]);
close(parent_io[1]);
write(child_io[1], dmenu_input, strlen(dmenu_input));
close(child_io[1]);
char buf[1024];
size_t len = read(parent_io[0], buf, 1023);
if (len == 0)
return;
buf[len - 1] = '\0';
}
close(child_io[1]);
int browser_pid = fork();
if (browser_pid == 0) {
execlp(browser, browser, (char *) NULL);
} else {
return;
}
}
void pause_signal_handler(int sig) void pause_signal_handler(int sig)
{ {
if (sig == SIGUSR1) { if (sig == SIGUSR1) {
@ -812,6 +864,11 @@ void handleXEvents(void)
&& close_all_ks.mask == ev.xkey.state) { && close_all_ks.mask == ev.xkey.state) {
move_all_to_history(); move_all_to_history();
} }
if (context_ks.str
&& XLookupKeysym(&ev.xkey, 0) == context_ks.sym
&& context_ks.mask == ev.xkey.state) {
context_menu();
}
} }
} }
} }
@ -1149,6 +1206,7 @@ void hide_win()
{ {
ungrab_key(&close_ks); ungrab_key(&close_ks);
ungrab_key(&close_all_ks); ungrab_key(&close_all_ks);
ungrab_key(&context_ks);
XUngrabButton(dc->dpy, AnyButton, AnyModifier, win); XUngrabButton(dc->dpy, AnyButton, AnyModifier, win);
XUnmapWindow(dc->dpy, win); XUnmapWindow(dc->dpy, win);
@ -1264,6 +1322,7 @@ void setup(void)
init_shortcut(&close_ks); init_shortcut(&close_ks);
init_shortcut(&close_all_ks); init_shortcut(&close_all_ks);
init_shortcut(&history_ks); init_shortcut(&history_ks);
init_shortcut(&context_ks);
grab_key(&close_ks); grab_key(&close_ks);
ungrab_key(&close_ks); ungrab_key(&close_ks);
@ -1271,6 +1330,8 @@ void setup(void)
ungrab_key(&close_all_ks); ungrab_key(&close_all_ks);
grab_key(&history_ks); grab_key(&history_ks);
ungrab_key(&history_ks); ungrab_key(&history_ks);
grab_key(&context_ks);
ungrab_key(&context_ks);
colors[LOW] = initcolor(dc, lowfgcolor, lowbgcolor); colors[LOW] = initcolor(dc, lowfgcolor, lowbgcolor);
colors[NORM] = initcolor(dc, normfgcolor, normbgcolor); colors[NORM] = initcolor(dc, normfgcolor, normbgcolor);
@ -1344,6 +1405,7 @@ void map_win(void)
grab_key(&close_ks); grab_key(&close_ks);
grab_key(&close_all_ks); grab_key(&close_all_ks);
grab_key(&context_ks);
setup_error_handler(); setup_error_handler();
XGrabButton(dc->dpy, AnyButton, AnyModifier, win, false, XGrabButton(dc->dpy, AnyButton, AnyModifier, win, false,
BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
@ -1498,6 +1560,10 @@ void load_options(char *cmdline_config_path)
startup_notification = option_get_bool("global", "startup_notification", startup_notification = option_get_bool("global", "startup_notification",
"-startup_notification", false, "print notification on startup"); "-startup_notification", false, "print notification on startup");
dmenu = option_get_string("global", "dmenu", "-dmenu", dmenu, "path to dmenu");
browser = option_get_string("global", "browser", "-browser", browser, "path to browser");
lowbgcolor = lowbgcolor =
option_get_string("urgency_low", "background", "-lb", lowbgcolor, option_get_string("urgency_low", "background", "-lb", lowbgcolor,
"Background color for notifcations with low urgency"); "Background color for notifcations with low urgency");
@ -1543,6 +1609,11 @@ void load_options(char *cmdline_config_path)
history_ks.str, history_ks.str,
"Shortcut to pop the last notification from history"); "Shortcut to pop the last notification from history");
context_ks.str =
option_get_string("shortcuts", "context", "-context_key",
context_ks.str,
"Shortcut for context menu");
print_notifications = print_notifications =
cmdline_get_bool("-print", false, cmdline_get_bool("-print", false,
"Print notifications to cmdline (DEBUG)"); "Print notifications to cmdline (DEBUG)");

10
dunstrc
View File

@ -94,6 +94,13 @@
# automatically after a crash. # automatically after a crash.
startup_notification = false startup_notification = false
# dmenu path
dmenu = "/usr/bin/dmenu"
# browser for opening urls in context menu
browser = /usr/bin/firefox
[shortcuts] [shortcuts]
# shortcuts are specified as [modifier+][modifier+]...key # shortcuts are specified as [modifier+][modifier+]...key
# available modifiers are 'ctrl', 'mod1' (the alt-key), 'mod2', 'mod3' # available modifiers are 'ctrl', 'mod1' (the alt-key), 'mod2', 'mod3'
@ -110,6 +117,9 @@
# On the US keyboard layout 'grave' is normally above TAB and left of '1'. # On the US keyboard layout 'grave' is normally above TAB and left of '1'.
history = ctrl+grave history = ctrl+grave
# context menu
context = ctrl+shift+period
[urgency_low] [urgency_low]
# IMPORTANT: colors have to be defined in quotation marks. # IMPORTANT: colors have to be defined in quotation marks.
# Otherwise the '#' and following would be interpreted as a comment. # Otherwise the '#' and following would be interpreted as a comment.

18
utils.c
View File

@ -1,3 +1,5 @@
#define _GNU_SOURCE
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
@ -46,6 +48,22 @@ char *string_replace(const char *needle, const char *replacement,
return tmp; return tmp;
} }
char *string_append(char *a, const char *b, const char *sep)
{
if (!a)
return strdup(b);
char *new;
if (!sep)
asprintf(&new, "%s%s", a, b);
else
asprintf(&new, "%s%s%s", a, sep, b);
free(a);
return new;
}
int digit_count(int i) int digit_count(int i)
{ {
int len = 0; int len = 0;

View File

@ -8,6 +8,8 @@ char *lskip(char *str);
char *string_replace(const char *needle, const char *replacement, char *string_replace(const char *needle, const char *replacement,
char *haystack); char *haystack);
char *string_append(char *a, const char *b, const char *sep);
/* exit with an error message */ /* exit with an error message */
void die(char *msg, int exit_value); void die(char *msg, int exit_value);