252 lines
7.1 KiB
Diff
252 lines
7.1 KiB
Diff
File wmenu/.git is a directory while file wmenud/.git is a regular file
|
|
diff -Nur wmenu/menu.c wmenud/menu.c
|
|
--- wmenu/menu.c 2026-03-31 04:31:08.735754566 +0200
|
|
+++ wmenud/menu.c 2026-03-31 04:31:00.976768869 +0200
|
|
@@ -172,7 +172,7 @@
|
|
}
|
|
|
|
// Add an item to the menu.
|
|
-void menu_add_item(struct menu *menu, char *text) {
|
|
+void menu_add_item(struct menu *menu, char *text, void *app_info) {
|
|
if ((menu->item_count & (menu->item_count - 1)) == 0) {
|
|
size_t alloc_size = menu->item_count ? 2 * menu->item_count : 1;
|
|
void *new_array = realloc(menu->items, sizeof(struct item) * alloc_size);
|
|
@@ -185,6 +185,7 @@
|
|
|
|
struct item *new = &menu->items[menu->item_count];
|
|
new->text = text;
|
|
+ new->app_info = app_info;
|
|
|
|
menu->item_count++;
|
|
}
|
|
@@ -593,10 +594,10 @@
|
|
case XKB_KEY_Return:
|
|
case XKB_KEY_KP_Enter:
|
|
if (shift) {
|
|
- menu->callback(menu, menu->input, true);
|
|
+ menu->callback(menu, menu->input, menu->sel->app_info, true);
|
|
} else {
|
|
char *text = menu->sel ? menu->sel->text : menu->input;
|
|
- menu->callback(menu, text, !ctrl);
|
|
+ menu->callback(menu, text, menu->sel->app_info, !ctrl);
|
|
}
|
|
break;
|
|
case XKB_KEY_Left:
|
|
diff -Nur wmenu/menu.h wmenud/menu.h
|
|
--- wmenu/menu.h 2026-03-31 04:31:08.735754566 +0200
|
|
+++ wmenud/menu.h 2026-03-31 04:31:00.976768869 +0200
|
|
@@ -6,13 +6,15 @@
|
|
#include <sys/types.h>
|
|
#include <xkbcommon/xkbcommon.h>
|
|
#include <wayland-client.h>
|
|
+#include <gio-unix-2.0/gio/gdesktopappinfo.h>
|
|
|
|
struct menu;
|
|
-typedef void (*menu_callback)(struct menu *menu, char *text, bool exit);
|
|
+typedef void (*menu_callback)(struct menu *menu, char *text, GAppInfo *app_info, bool exit);
|
|
|
|
// A menu item.
|
|
struct item {
|
|
char *text;
|
|
+ GAppInfo *app_info;
|
|
int width;
|
|
struct item *prev_match; // previous matching item
|
|
struct item *next_match; // next matching item
|
|
@@ -84,7 +86,7 @@
|
|
struct menu *menu_create(menu_callback callback);
|
|
void menu_destroy(struct menu *menu);
|
|
void menu_getopts(struct menu *menu, int argc, char *argv[]);
|
|
-void menu_add_item(struct menu *menu, char *text);
|
|
+void menu_add_item(struct menu *menu, char *text, void *app_info);
|
|
void menu_sort_and_deduplicate(struct menu *menu);
|
|
void menu_calc_height(struct menu *menu);
|
|
void menu_invalidate(struct menu *menu);
|
|
diff -Nur wmenu/meson.build wmenud/meson.build
|
|
--- wmenu/meson.build 2026-03-31 04:31:08.735754566 +0200
|
|
+++ wmenud/meson.build 2026-03-31 04:31:00.976768869 +0200
|
|
@@ -7,6 +7,7 @@
|
|
'c_std=c11',
|
|
'warning_level=2',
|
|
'werror=true',
|
|
+ 'optimization=3',
|
|
]
|
|
)
|
|
|
|
@@ -19,6 +20,7 @@
|
|
'-Wno-unused-parameter',
|
|
'-Wundef',
|
|
'-Wvla',
|
|
+ '-Wno-discarded-qualifiers',
|
|
]), language : 'c')
|
|
|
|
cairo = dependency('cairo')
|
|
@@ -27,6 +29,8 @@
|
|
wayland_client = dependency('wayland-client')
|
|
wayland_protos = dependency('wayland-protocols')
|
|
xkbcommon = dependency('xkbcommon')
|
|
+glib = dependency('glib-2.0')
|
|
+gio_unix = dependency('gio-unix-2.0')
|
|
|
|
rt = cc.find_library('rt')
|
|
|
|
@@ -78,3 +82,28 @@
|
|
],
|
|
install: true,
|
|
)
|
|
+
|
|
+executable(
|
|
+ 'wmenu-drun',
|
|
+ files(
|
|
+ 'menu.c',
|
|
+ 'pango.c',
|
|
+ 'pool-buffer.c',
|
|
+ 'render.c',
|
|
+ 'wayland.c',
|
|
+ 'wmenu-drun.c',
|
|
+ ),
|
|
+ dependencies: [
|
|
+ cairo,
|
|
+ client_protos,
|
|
+ pango,
|
|
+ pangocairo,
|
|
+ rt,
|
|
+ wayland_client,
|
|
+ wayland_protos,
|
|
+ xkbcommon,
|
|
+ glib,
|
|
+ gio_unix,
|
|
+ ],
|
|
+ install: true,
|
|
+)
|
|
diff -Nur wmenu/wmenu.c wmenud/wmenu.c
|
|
--- wmenu/wmenu.c 2026-03-31 04:31:08.736754564 +0200
|
|
+++ wmenud/wmenu.c 2026-03-31 04:31:00.979768864 +0200
|
|
@@ -2,6 +2,7 @@
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
+#include <gio-unix-2.0/gio/gdesktopappinfo.h>
|
|
|
|
#include "menu.h"
|
|
#include "wayland.h"
|
|
@@ -13,11 +14,11 @@
|
|
if (p) {
|
|
*p = '\0';
|
|
}
|
|
- menu_add_item(menu, strdup(buf));
|
|
+ menu_add_item(menu, strdup(buf), NULL);
|
|
}
|
|
}
|
|
|
|
-static void print_item(struct menu *menu, char *text, bool exit) {
|
|
+static void print_item(struct menu *menu, char *text, GAppInfo *app_info, bool exit) {
|
|
puts(text);
|
|
fflush(stdout);
|
|
if (exit) {
|
|
diff -Nur wmenu/wmenu-drun.c wmenud/wmenu-drun.c
|
|
--- wmenu/wmenu-drun.c 1970-01-01 01:00:00.000000000 +0100
|
|
+++ wmenud/wmenu-drun.c 2026-03-31 21:24:43.667365628 +0200
|
|
@@ -0,0 +1,73 @@
|
|
+#define _POSIX_C_SOURCE 200809L
|
|
+#include <dirent.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <unistd.h>
|
|
+#include <gio-unix-2.0/gio/gdesktopappinfo.h>
|
|
+
|
|
+#include "menu.h"
|
|
+#include "wayland.h"
|
|
+#include "xdg-activation-v1-client-protocol.h"
|
|
+
|
|
+static void read_items(struct menu *menu) {
|
|
+ GList* list = g_app_info_get_all();
|
|
+ GList* item;
|
|
+ for(item = list; item; item = item->next) {
|
|
+ if (g_app_info_should_show(item->data) == FALSE) {
|
|
+ continue;
|
|
+ }
|
|
+ const char *name = g_app_info_get_name(item->data);
|
|
+ menu_add_item(menu, name, item->data);
|
|
+ }
|
|
+ menu_sort_and_deduplicate(menu);
|
|
+}
|
|
+
|
|
+struct command {
|
|
+ struct menu *menu;
|
|
+ char *text;
|
|
+ GAppInfo *app_info;
|
|
+ bool exit;
|
|
+};
|
|
+
|
|
+static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token,
|
|
+ const char *token) {
|
|
+ struct command *cmd = data;
|
|
+ xdg_activation_token_v1_destroy(activation_token);
|
|
+
|
|
+ GAppLaunchContext *context = g_app_launch_context_new(); // Not strictly necessary.
|
|
+ g_app_info_launch(cmd->app_info, NULL, context, NULL);
|
|
+ setenv("XDG_ACTIVATION_TOKEN", token, true);
|
|
+ xdg_activation_token_v1_destroy(activation_token);
|
|
+ cmd->menu->exit = true;
|
|
+}
|
|
+
|
|
+static const struct xdg_activation_token_v1_listener activation_token_listener = {
|
|
+ .done = activation_token_done,
|
|
+};
|
|
+
|
|
+static void exec_item(struct menu *menu, char *text, GAppInfo *app_info, bool exit) {
|
|
+ struct command *cmd = calloc(1, sizeof(struct command));
|
|
+ cmd->menu = menu;
|
|
+ cmd->text = strdup(text);
|
|
+ cmd->app_info = app_info;
|
|
+ if (cmd->app_info == NULL) {
|
|
+ printf("app info is nil\n");
|
|
+ }
|
|
+ cmd->exit = exit;
|
|
+
|
|
+ struct xdg_activation_v1 *activation = context_get_xdg_activation(menu->context);
|
|
+ struct xdg_activation_token_v1 *activation_token = xdg_activation_v1_get_activation_token(activation);
|
|
+ xdg_activation_token_v1_set_surface(activation_token, context_get_surface(menu->context));
|
|
+ xdg_activation_token_v1_add_listener(activation_token, &activation_token_listener, cmd);
|
|
+ xdg_activation_token_v1_commit(activation_token);
|
|
+}
|
|
+
|
|
+int main(int argc, char *argv[]) {
|
|
+ struct menu *menu = menu_create(exec_item);
|
|
+ menu_getopts(menu, argc, argv);
|
|
+ read_items(menu);
|
|
+ int status = menu_run(menu);
|
|
+ menu_destroy(menu);
|
|
+ return status;
|
|
+}
|
|
diff -Nur wmenu/wmenu-run.c wmenud/wmenu-run.c
|
|
--- wmenu/wmenu-run.c 2026-03-31 04:31:08.735754566 +0200
|
|
+++ wmenud/wmenu-run.c 2026-03-31 04:31:00.979768864 +0200
|
|
@@ -4,6 +4,7 @@
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
+#include <gio-unix-2.0/gio/gdesktopappinfo.h>
|
|
|
|
#include "menu.h"
|
|
#include "wayland.h"
|
|
@@ -20,7 +21,7 @@
|
|
if (ent->d_name[0] == '.') {
|
|
continue;
|
|
}
|
|
- menu_add_item(menu, strdup(ent->d_name));
|
|
+ menu_add_item(menu, strdup(ent->d_name), NULL);
|
|
}
|
|
closedir(dir);
|
|
}
|
|
@@ -55,7 +56,7 @@
|
|
.done = activation_token_done,
|
|
};
|
|
|
|
-static void exec_item(struct menu *menu, char *text, bool exit) {
|
|
+static void exec_item(struct menu *menu, char *text, GAppInfo *app_info, bool exit) {
|
|
struct command *cmd = calloc(1, sizeof(struct command));
|
|
cmd->menu = menu;
|
|
cmd->text = strdup(text);
|