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 */
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?
* possible values:
* FOLLOW_NONE
@ -60,6 +65,9 @@ keyboard_shortcut close_all_ks = {.str = "none",
keyboard_shortcut history_ks = {.str = "none",
.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[] = {
/* 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 print_version(void);
str_array *extract_urls(const char *str);
void context_menu(void);
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);
@ -153,6 +154,57 @@ str_array *extract_urls( const char * to_match)
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)
{
if (sig == SIGUSR1) {
@ -812,6 +864,11 @@ void handleXEvents(void)
&& close_all_ks.mask == ev.xkey.state) {
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_all_ks);
ungrab_key(&context_ks);
XUngrabButton(dc->dpy, AnyButton, AnyModifier, win);
XUnmapWindow(dc->dpy, win);
@ -1264,6 +1322,7 @@ void setup(void)
init_shortcut(&close_ks);
init_shortcut(&close_all_ks);
init_shortcut(&history_ks);
init_shortcut(&context_ks);
grab_key(&close_ks);
ungrab_key(&close_ks);
@ -1271,6 +1330,8 @@ void setup(void)
ungrab_key(&close_all_ks);
grab_key(&history_ks);
ungrab_key(&history_ks);
grab_key(&context_ks);
ungrab_key(&context_ks);
colors[LOW] = initcolor(dc, lowfgcolor, lowbgcolor);
colors[NORM] = initcolor(dc, normfgcolor, normbgcolor);
@ -1344,6 +1405,7 @@ void map_win(void)
grab_key(&close_ks);
grab_key(&close_all_ks);
grab_key(&context_ks);
setup_error_handler();
XGrabButton(dc->dpy, AnyButton, AnyModifier, win, false,
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", 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 =
option_get_string("urgency_low", "background", "-lb", lowbgcolor,
"Background color for notifcations with low urgency");
@ -1543,6 +1609,11 @@ void load_options(char *cmdline_config_path)
history_ks.str,
"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 =
cmdline_get_bool("-print", false,
"Print notifications to cmdline (DEBUG)");

10
dunstrc
View File

@ -94,6 +94,13 @@
# automatically after a crash.
startup_notification = false
# dmenu path
dmenu = "/usr/bin/dmenu"
# browser for opening urls in context menu
browser = /usr/bin/firefox
[shortcuts]
# shortcuts are specified as [modifier+][modifier+]...key
# 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'.
history = ctrl+grave
# context menu
context = ctrl+shift+period
[urgency_low]
# IMPORTANT: colors have to be defined in quotation marks.
# 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 <ctype.h>
#include <stdlib.h>
@ -46,6 +48,22 @@ char *string_replace(const char *needle, const char *replacement,
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 len = 0;

View File

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