Support xdg_activation_v1 protocol
This commit is contained in:
parent
41b2e8b1e1
commit
cf6f5b9d06
7 changed files with 71 additions and 5 deletions
|
@ -27,7 +27,7 @@ See wmenu(1)
|
||||||
To use wmenu with Sway, you can add the following to your configuration file:
|
To use wmenu with Sway, you can add the following to your configuration file:
|
||||||
|
|
||||||
```
|
```
|
||||||
set $menu dmenu_path | wmenu | xargs swaymsg exec --
|
set $menu wmenu_run
|
||||||
bindsym $mod+d exec $menu
|
bindsym $mod+d exec $menu
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ wmenu - dynamic menu for Wayland
|
||||||
|
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
|
|
||||||
*wmenu* [-biPv] \
|
*wmenu* [-biPvx] \
|
||||||
[-f _font_] \
|
[-f _font_] \
|
||||||
[-l _lines_] \
|
[-l _lines_] \
|
||||||
[-o _output_] \
|
[-o _output_] \
|
||||||
|
@ -37,6 +37,9 @@ to those matching the tokens in the input.
|
||||||
*-v*
|
*-v*
|
||||||
prints version information to stdout, then exits.
|
prints version information to stdout, then exits.
|
||||||
|
|
||||||
|
*-x*
|
||||||
|
wmenu will execute the selected item.
|
||||||
|
|
||||||
*-f* _font_
|
*-f* _font_
|
||||||
defines the font used. For more information, see
|
defines the font used. For more information, see
|
||||||
https://docs.gtk.org/Pango/type_func.FontDescription.from_string.html
|
https://docs.gtk.org/Pango/type_func.FontDescription.from_string.html
|
||||||
|
|
4
main.c
4
main.c
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
#include "xdg-activation-v1-client-protocol.h"
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
static void noop() {
|
static void noop() {
|
||||||
|
@ -203,6 +204,8 @@ static void handle_global(void *data, struct wl_registry *registry,
|
||||||
wl_output_set_user_data(wl_output, output);
|
wl_output_set_user_data(wl_output, output);
|
||||||
wl_output_add_listener(wl_output, &output_listener, output);
|
wl_output_add_listener(wl_output, &output_listener, output);
|
||||||
menu_add_output(menu, output);
|
menu_add_output(menu, output);
|
||||||
|
} else if (strcmp(interface, xdg_activation_v1_interface.name) == 0) {
|
||||||
|
menu->activation = wl_registry_bind(registry, name, &xdg_activation_v1_interface, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,6 +230,7 @@ static void menu_connect(struct menu *menu) {
|
||||||
assert(menu->seat != NULL);
|
assert(menu->seat != NULL);
|
||||||
assert(menu->data_device_manager != NULL);
|
assert(menu->data_device_manager != NULL);
|
||||||
assert(menu->layer_shell != NULL);
|
assert(menu->layer_shell != NULL);
|
||||||
|
assert(menu->activation != NULL);
|
||||||
menu->registry = registry;
|
menu->registry = registry;
|
||||||
|
|
||||||
// Get data device for seat
|
// Get data device for seat
|
||||||
|
|
58
menu.c
58
menu.c
|
@ -21,6 +21,7 @@
|
||||||
#include "pango.h"
|
#include "pango.h"
|
||||||
#include "pool-buffer.h"
|
#include "pool-buffer.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
#include "xdg-activation-v1-client-protocol.h"
|
||||||
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
#include "wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
// Creates and returns a new menu.
|
// Creates and returns a new menu.
|
||||||
|
@ -89,11 +90,11 @@ static bool parse_color(const char *color, uint32_t *result) {
|
||||||
// Parse menu options from command line arguments.
|
// Parse menu options from command line arguments.
|
||||||
void menu_getopts(struct menu *menu, int argc, char *argv[]) {
|
void menu_getopts(struct menu *menu, int argc, char *argv[]) {
|
||||||
const char *usage =
|
const char *usage =
|
||||||
"Usage: wmenu [-biPv] [-f font] [-l lines] [-o output] [-p prompt]\n"
|
"Usage: wmenu [-biPvx] [-f font] [-l lines] [-o output] [-p prompt]\n"
|
||||||
"\t[-N color] [-n color] [-M color] [-m color] [-S color] [-s color]\n";
|
"\t[-N color] [-n color] [-M color] [-m color] [-S color] [-s color]\n";
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "bhiPvf:l:o:p:N:n:M:m:S:s:")) != -1) {
|
while ((opt = getopt(argc, argv, "bhiPvxf:l:o:p:N:n:M:m:S:s:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'b':
|
case 'b':
|
||||||
menu->bottom = true;
|
menu->bottom = true;
|
||||||
|
@ -107,6 +108,9 @@ void menu_getopts(struct menu *menu, int argc, char *argv[]) {
|
||||||
case 'v':
|
case 'v':
|
||||||
puts("wmenu " VERSION);
|
puts("wmenu " VERSION);
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
case 'x':
|
||||||
|
menu->exec = true;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
menu->font = optarg;
|
menu->font = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -409,6 +413,53 @@ static void movewordedge(struct menu *menu, int dir) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Information needed to execute an item.
|
||||||
|
struct executable {
|
||||||
|
struct menu *menu;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Executes an item with an activation token.
|
||||||
|
static void execute(struct executable *exe, const char *token) {
|
||||||
|
menu_destroy(exe->menu);
|
||||||
|
|
||||||
|
setenv("XDG_ACTIVATION_TOKEN", token, true);
|
||||||
|
execlp(exe->name, exe->name, NULL);
|
||||||
|
|
||||||
|
// Handle execution failure
|
||||||
|
fprintf(stderr, "Failed to execute selection: %s\n", strerror(errno));
|
||||||
|
free(exe->name);
|
||||||
|
free(exe);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token,
|
||||||
|
const char *token) {
|
||||||
|
struct executable *exe = data;
|
||||||
|
xdg_activation_token_v1_destroy(activation_token);
|
||||||
|
execute(exe, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdg_activation_token_v1_listener activation_token_listener = {
|
||||||
|
.done = activation_token_done,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Executes the selected item.
|
||||||
|
static void menu_exec(struct menu *menu) {
|
||||||
|
if (!menu->sel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct executable *exe = calloc(1, sizeof(struct executable));
|
||||||
|
exe->menu = menu;
|
||||||
|
exe->name = strdup(menu->sel->text);
|
||||||
|
|
||||||
|
struct xdg_activation_token_v1 *activation_token = xdg_activation_v1_get_activation_token(menu->activation);
|
||||||
|
xdg_activation_token_v1_set_surface(activation_token, menu->surface);
|
||||||
|
xdg_activation_token_v1_add_listener(activation_token, &activation_token_listener, exe);
|
||||||
|
xdg_activation_token_v1_commit(activation_token);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle a keypress.
|
// Handle a keypress.
|
||||||
void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
|
void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
|
||||||
xkb_keysym_t sym) {
|
xkb_keysym_t sym) {
|
||||||
|
@ -588,6 +639,8 @@ void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
|
||||||
puts(menu->input);
|
puts(menu->input);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
menu->exit = true;
|
menu->exit = true;
|
||||||
|
} else if (menu->exec) {
|
||||||
|
menu_exec(menu);
|
||||||
} else {
|
} else {
|
||||||
char *text = menu->sel ? menu->sel->text : menu->input;
|
char *text = menu->sel ? menu->sel->text : menu->input;
|
||||||
puts(text);
|
puts(text);
|
||||||
|
@ -750,6 +803,7 @@ void menu_destroy(struct menu *menu) {
|
||||||
wl_data_device_destroy(menu->data_device);
|
wl_data_device_destroy(menu->data_device);
|
||||||
wl_surface_destroy(menu->surface);
|
wl_surface_destroy(menu->surface);
|
||||||
zwlr_layer_surface_v1_destroy(menu->layer_surface);
|
zwlr_layer_surface_v1_destroy(menu->layer_surface);
|
||||||
|
xdg_activation_v1_destroy(menu->activation);
|
||||||
|
|
||||||
free_pages(menu);
|
free_pages(menu);
|
||||||
free_items(menu);
|
free_items(menu);
|
||||||
|
|
4
menu.h
4
menu.h
|
@ -4,6 +4,7 @@
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include "pool-buffer.h"
|
#include "pool-buffer.h"
|
||||||
|
#include "xdg-activation-v1-client-protocol.h"
|
||||||
|
|
||||||
// A menu item.
|
// A menu item.
|
||||||
struct item {
|
struct item {
|
||||||
|
@ -55,6 +56,8 @@ struct menu {
|
||||||
int (*strncmp)(const char *, const char *, size_t);
|
int (*strncmp)(const char *, const char *, size_t);
|
||||||
// Whether the input is a password
|
// Whether the input is a password
|
||||||
bool passwd;
|
bool passwd;
|
||||||
|
// Whether to execute the selected item
|
||||||
|
bool exec;
|
||||||
// The font used to display the menu
|
// The font used to display the menu
|
||||||
char *font;
|
char *font;
|
||||||
// The number of lines to list items vertically
|
// The number of lines to list items vertically
|
||||||
|
@ -78,6 +81,7 @@ struct menu {
|
||||||
struct wl_data_device_manager *data_device_manager;
|
struct wl_data_device_manager *data_device_manager;
|
||||||
struct zwlr_layer_shell_v1 *layer_shell;
|
struct zwlr_layer_shell_v1 *layer_shell;
|
||||||
struct output *output_list;
|
struct output *output_list;
|
||||||
|
struct xdg_activation_v1 *activation;
|
||||||
|
|
||||||
struct keyboard *keyboard;
|
struct keyboard *keyboard;
|
||||||
struct wl_data_device *data_device;
|
struct wl_data_device *data_device;
|
||||||
|
|
|
@ -12,6 +12,7 @@ endif
|
||||||
|
|
||||||
protocols = [
|
protocols = [
|
||||||
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
[wl_protocol_dir, 'stable/xdg-shell/xdg-shell.xml'],
|
||||||
|
[wl_protocol_dir, 'staging/xdg-activation/xdg-activation-v1.xml'],
|
||||||
['wlr-layer-shell-unstable-v1.xml'],
|
['wlr-layer-shell-unstable-v1.xml'],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,4 @@ path() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
path | wmenu "$@" | ${SHELL:-"/bin/sh"} &
|
path | wmenu -x "$@"
|
||||||
|
|
Loading…
Add table
Reference in a new issue