diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | util.h | 6 | ||||
-rw-r--r-- | xlnch.c | 296 |
3 files changed, 133 insertions, 174 deletions
@@ -1,12 +1,13 @@ +PKG_CONFIG ?= pkg-config TARGET=xlnch PREFIX?=/usr/local MANUALS=$(PREFIX)/share/man SRC=*.c CC=gcc -CFLAGS=-D_GNU_SOURCE -std=c99 -pedantic +CFLAGS=-Wall $(shell $(PKG_CONFIG) --cflags gtk4) REL_FLAGS=-O3 DBG_FLAGS=-Wall -g3 -LIBS=-l X11 +LIBS=$(shell $(PKG_CONFIG) --libs gtk4) make: $(SRC) $(CC) $(REL_FLAGS) $(CFLAGS) -o $(TARGET) $^ $(LIBS) @@ -2,8 +2,10 @@ #define XLNCH_UTIL_H #include <stdarg.h> - -#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> void die(const char *fmt, ...) { va_list ap; @@ -21,17 +21,17 @@ * Brian Hammond 2/9/96. http://mech.math.msu.su/~nap/2/GWindow/xintro.html */ -#include <ctype.h> +#include <X11/X.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <time.h> #include <wordexp.h> -#include <X11/Xlib.h> -#include <X11/Xos.h> -#include <X11/Xutil.h> +#include <gtk/gtk.h> + +#include "gtk/gtkshortcut.h" #include "util.h" #define BUF_SIZE 2048 @@ -48,83 +48,13 @@ struct lnch_t { char cmd[1024]; } lnch[MAX_ENTRIES]; -unsigned int idx = 0; +GtkWidget *window = NULL; -Colormap cm; -Display *display; -GC gc; -int screen; -Window root, win; -XColor red; -XFontStruct *font; +unsigned int idx = 0; int w_width = 0; int w_height = 0; -void get_curson_pos(int *x, int *y) -{ - int win_x_return, win_y_return; - unsigned int mask_return; - Window root_return, child_return; - - XQueryPointer(display, root, &root_return, &child_return, - x, y, &win_x_return, &win_y_return, &mask_return); -} - -void init() -{ - XWindowAttributes wa; - XSetWindowAttributes swa; - - display = XOpenDisplay(NULL); - screen = DefaultScreen(display); - root = RootWindow(display, screen); - if (!XGetWindowAttributes(display, root, &wa)) - die("could not get embedding window attributes: 0x%lx", root); - - gc = XCreateGC(display, root, 0, NULL); - XSetLineAttributes(display, gc, 1, LineSolid, CapButt, JoinMiter); - - cm = DefaultColormap(display, screen); - if (!XAllocNamedColor(display, cm, "red", &red, &red)) { - fprintf(stderr, - "XAllocNamedColor - failed to allocated 'red' color.\n"); - exit(1); - } - - swa.override_redirect = True; - swa.background_pixel = BlackPixel(display, screen); - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - - int x, y; - get_curson_pos(&x, &y); - - int height = 16 + (9 + 3) * w_height - 3 + 16, - width = 16 + w_width * 11; - win = XCreateWindow(display, root, x, y, width, height, 0, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, - &swa); - - font = XLoadQueryFont(display, FONTNAME); - /* If the font could not be loaded, revert to the "fixed" font. */ - if (!font) { - fprintf(stderr, "unable to load font %s: using fixed\n", FONTNAME); - font = XLoadQueryFont(display, "fixed"); - } - XSetFont(display, gc, font->fid); - - XMapRaised(display, win); - XRaiseWindow(display, win); -} - -void close_x() -{ - XFreeGC(display, gc); - XDestroyWindow(display, win); - XCloseDisplay(display); -} - int parse_line(char *line) { char *token; @@ -221,118 +151,142 @@ int run_cmd(char *cmd) return rc; } -void grabfocus() +gboolean +key_pressed_callback ( + GtkEventControllerKey* self, + guint keyval, + guint keycode, + GdkModifierType state, + gpointer user_data +) { - struct timespec ts = {.tv_sec = 0,.tv_nsec = 10000000 }; - Window focuswin; - int i, revertwin; - - for (i = 0; i < 100; ++i) { - XGetInputFocus(display, &focuswin, &revertwin); - if (focuswin == win) - return; - XSetInputFocus(display, win, RevertToParent, CurrentTime); - nanosleep(&ts, NULL); + if ((state == GDK_CONTROL_MASK && keycode == 42) || keycode == 9) { + gtk_window_destroy(GTK_WINDOW(window)); + die("diead"); } - printf("cannot grab focus\n"); -} - -void grabkeyboard() -{ - struct timespec ts = {.tv_sec = 0,.tv_nsec = 1000000 }; - int i; - - /* try to grab keyboard, we may have to wait for another process to ungrab */ - for (i = 0; i < 1000; i++) { - if (XGrabKeyboard(display, root, True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) - return; - nanosleep(&ts, NULL); + for (unsigned int i = 0; i < idx; i++) { + if (lnch[i].key == keyval) { + if (lnch[i].exits) { + gtk_window_destroy(GTK_WINDOW(window)); + } + run_cmd(lnch[i].cmd); + if (lnch[i].exits) { + die("diead"); + } + gtk_widget_grab_focus (window); + + } } - printf("Cannot grab keyboard\n"); + return false; } void draw_text() { + g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", TRUE, NULL); + window = gtk_window_new(); + gtk_window_set_title(GTK_WINDOW(window), "xlnch"); + gtk_window_set_default_size(GTK_WINDOW(window), 200, 440); + gtk_window_set_resizable(GTK_WINDOW(window), FALSE); + gtk_window_set_decorated(GTK_WINDOW(window), FALSE); + + + GtkEventController* ec = gtk_event_controller_key_new(); + g_signal_connect(G_OBJECT(ec), "key_pressed", G_CALLBACK (key_pressed_callback), NULL); + + gtk_widget_add_controller (window, GTK_EVENT_CONTROLLER (ec)); + + /* GtkWidget *spinner = gtk_spinner_new(); */ + /* gtk_window_set_child(GTK_WINDOW(window), spinner); */ + /* gtk_spinner_start(GTK_SPINNER(spinner)); */ + + char text[2048]; - int x = 10, y = 2; + char bigbuf[1024*100] = ""; + //int x = 10, y = 2; for (unsigned int i = 0; i < idx; i++) { - if (lnch[i].exits) { - XSetForeground(display, gc, WhitePixel(display, screen)); - } else { - XSetForeground(display, gc, red.pixel); - } - sprintf(text, "%c: %s", lnch[i].key, lnch[i].desc); - XDrawString(display, win, gc, x, y += 13, text, strlen(text)); + if (lnch[i].exits) { + sprintf(text, "%c: %s\n", lnch[i].key, lnch[i].desc); + strcat(bigbuf, text); + // XSetForeground(display, gc, WhitePixel(display, screen)); + } else { + sprintf(text, "<span foreground=\"red\">%c</span>: %s\n", lnch[i].key, lnch[i].desc); + strcat(bigbuf, text); + // XSetForeground(display, gc, red.pixel); + } + + // XDrawString(display, win, gc, x, y += 13, text, strlen(text)); } + GtkWidget *label = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(label),bigbuf); + gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER); + gtk_window_set_child(GTK_WINDOW(window), label); + + gtk_window_present(GTK_WINDOW(window)); + } int run() { - XEvent event; - KeySym keysym; - char text[255]; - int flag, rc; + //char text[255]; + //int flag, rc; - init(); + //init(); draw_text(); - grabkeyboard(); - grabfocus(); - while (1) { - XNextEvent(display, &event); - - if (event.type == Expose && event.xexpose.count == 0) { - /* the window was exposed redraw it! */ - XClearWindow(display, win); - draw_text(); - } - - /* Keep window in view */ - else if (event.type == VisibilityNotify && - event.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(display, win); - - else if (event.type == KeyPress) { - /* C-g and ESC quit */ - if ((event.xkey.state == 4 && event.xkey.keycode == 42) /* => C-g */ - ||event.xkey.keycode == 9) { /* => ESC */ - close_x(); - return 0; - } - - for (unsigned int i = 0; i < idx; i++) { - char tmp[128] = ""; - // get configured key - tmp[0] = lnch[i].key; - tmp[1] = '\0'; - // convert to keysym, and then to keycode Keycodes are consistent - // across layouts but may vary between different keyboard models. - // For example, the keycode for the "A" key might differ between - // a US QWERTY keyboard and a French AZERTY keyboard. - if (XKeysymToKeycode(display, XStringToKeysym(tmp)) == event.xkey.keycode) { - rc = run_cmd(lnch[i].cmd); - flag = 1; - if (lnch[i].exits) { - close_x(); - return rc; - } - } - } - - /* Q and q quit as well, as long as they don't match anything */ - if (!flag && event.xkey.keycode == 24) { /* Q or q */ - close_x(); - return 0; - } - } - - else if (event.type == FocusIn) { - if (event.xfocus.window != win) { - grabfocus(); - } - } + g_main_context_iteration(NULL, TRUE); + // XNextEvent(display, &event); + + // if (event.type == Expose && event.xexpose.count == 0) { + // /* the window was exposed redraw it! */ + // XClearWindow(display, win); + // draw_text(); + // } + + // /* Keep window in view */ + // else if (event.type == VisibilityNotify && + // event.xvisibility.state != VisibilityUnobscured) + // XRaiseWindow(display, win); + + // else if (event.type == KeyPress) { + // /* C-g and ESC quit */ + // if ((event.xkey.state == 4 && event.xkey.keycode == 42) /* => C-g */ + // ||event.xkey.keycode == 9) { /* => ESC */ + // close_x(); + // return 0; + // } + + // for (unsigned int i = 0; i < idx; i++) { + // char tmp[128] = ""; + // // get configured key + // tmp[0] = lnch[i].key; + // tmp[1] = '\0'; + // // convert to keysym, and then to keycode Keycodes are consistent + // // across layouts but may vary between different keyboard models. + // // For example, the keycode for the "A" key might differ between + // // a US QWERTY keyboard and a French AZERTY keyboard. + // if (XKeysymToKeycode(display, XStringToKeysym(tmp)) == event.xkey.keycode) { + // rc = run_cmd(lnch[i].cmd); + // flag = 1; + // if (lnch[i].exits) { + // close_x(); + // return rc; + // } + // } + // } + + // /* Q and q quit as well, as long as they don't match anything */ + // if (!flag && event.xkey.keycode == 24) { /* Q or q */ + // close_x(); + // return 0; + // } + // } + + // else if (event.type == FocusIn) { + // if (event.xfocus.window != win) { + // grabfocus(); + // } + // } } } @@ -341,6 +295,8 @@ int main(int argc, char *argv[]) int rc, n = 1; FILE *f; + gtk_init(); + if ((argc > 1) && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h") || !strcmp(argv[1], "-?"))) { |