Add -1 flag (single instance)

This commit is contained in:
sh!zeeg 2024-12-29 01:42:09 +03:00
parent e2542d34ed
commit 577d5759a7
5 changed files with 50 additions and 3 deletions

View file

@ -6,7 +6,7 @@ wmenu - dynamic menu for Wayland
# SYNOPSIS
*wmenu* [-biPv] \
*wmenu* [-1biPv] \
[-f _font_] \
[-l _lines_] \
[-o _output_] \
@ -29,6 +29,9 @@ $PATH and runs the result.
# OPTIONS
*-1*
allow only one instance.
*-b*
wmenu appears at the bottom of the screen.

7
menu.c
View file

@ -85,12 +85,15 @@ static bool parse_color(const char *color, uint32_t *result) {
// Parse menu options from command line arguments.
void menu_getopts(struct menu *menu, int argc, char *argv[]) {
const char *usage =
"Usage: wmenu [-biPv] [-f font] [-l lines] [-o output] [-p prompt]\n"
"Usage: wmenu [-1biPv] [-f font] [-l lines] [-o output] [-p prompt]\n"
"\t[-N color] [-n color] [-M color] [-m color] [-S color] [-s color]\n";
int opt;
while ((opt = getopt(argc, argv, "bhiPvf:l:o:p:N:n:M:m:S:s:")) != -1) {
while ((opt = getopt(argc, argv, "1bhiPvf:l:o:p:N:n:M:m:S:s:")) != -1) {
switch (opt) {
case '1':
menu->single_instance = true;
break;
case 'b':
menu->bottom = true;
break;

2
menu.h
View file

@ -29,6 +29,8 @@ struct page {
// Menu state.
struct menu {
// Allow only one instance
bool single_instance;
// Whether the menu appears at the bottom of the screen
bool bottom;
// The function used to match menu items

View file

@ -4,6 +4,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
#include "menu.h"
#include "wayland.h"
@ -71,6 +73,23 @@ static void exec_item(struct menu *menu, char *text, bool exit) {
int main(int argc, char *argv[]) {
struct menu *menu = menu_create(exec_item);
menu_getopts(menu, argc, argv);
if (menu->single_instance) {
// the following code was copied from `bemenu`, thanks.
char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
char buffer[1024];
char *menu_lock_location = (xdg_runtime_dir == NULL ? "/tmp" : xdg_runtime_dir);
snprintf(buffer, sizeof(buffer), "%s/wmenu.lock", menu_lock_location);
// Create a read-write lock file(if not already exists),
// closes on exec. Creates in tmp due to permissions.
int menu_lock = open(buffer, O_CREAT | O_RDWR | O_CLOEXEC, 0666);
// If we cannot set the lock/the lock is already present.
if (flock(menu_lock, LOCK_EX | LOCK_NB) == -1) {
fprintf(stderr, "\"%s\" instance is already running\n", argv[0]);
exit(EXIT_FAILURE);
}
}
read_items(menu);
int status = menu_run(menu);
menu_destroy(menu);

20
wmenu.c
View file

@ -1,7 +1,10 @@
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/file.h>
#include "menu.h"
#include "wayland.h"
@ -28,6 +31,23 @@ static void print_item(struct menu *menu, char *text, bool exit) {
int main(int argc, char *argv[]) {
struct menu *menu = menu_create(print_item);
menu_getopts(menu, argc, argv);
if (menu->single_instance) {
// the following code was copied from `bemenu`, thanks.
char *xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
char buffer[1024];
char *menu_lock_location = (xdg_runtime_dir == NULL ? "/tmp" : xdg_runtime_dir);
snprintf(buffer, sizeof(buffer), "%s/wmenu.lock", menu_lock_location);
// Create a read-write lock file(if not already exists),
// closes on exec. Creates in tmp due to permissions.
int menu_lock = open(buffer, O_CREAT | O_RDWR | O_CLOEXEC, 0666);
// If we cannot set the lock/the lock is already present.
if (flock(menu_lock, LOCK_EX | LOCK_NB) == -1) {
fprintf(stderr, "\"%s\" instance is already running\n", argv[0]);
exit(EXIT_FAILURE);
}
}
read_items(menu);
int status = menu_run(menu);
menu_destroy(menu);