Add support for xatom search action

This commit is contained in:
fenze 2022-05-10 23:47:17 +02:00
parent b0f9f5f421
commit 035a345158
7 changed files with 170 additions and 26 deletions

View File

@ -8,9 +8,11 @@ static const char *homepage = "https://duckduckgo.com";
#define MODKEY GDK_CONTROL_MASK
static Key keys[] = {
{ MODKEY, GDK_KEY_h, goback },
{ MODKEY, GDK_KEY_l, goforward },
{ MODKEY, GDK_KEY_y, copy_url },
{ MODKEY, GDK_KEY_p, paste_url },
{ 0, GDK_KEY_F11, fullscreen }
{ MODKEY, GDK_KEY_h, goback },
{ MODKEY, GDK_KEY_l, goforward },
{ MODKEY, GDK_KEY_y, copy_url },
{ MODKEY, GDK_KEY_p, paste_url },
{ 0, GDK_KEY_F11, fullscreen },
{ MODKEY|SHIFT, GDK_KEY_i, inspector },
{ MODKEY, GDK_KEY_e, search }
};

View File

@ -3,7 +3,7 @@
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#define NONE 4
#define SHIFT GDK_SHIFT_MASK
typedef struct {
unsigned modkey;
@ -16,5 +16,7 @@ enum {
goforward,
copy_url,
paste_url,
fullscreen
fullscreen,
inspector,
search
};

View File

@ -1,6 +1,6 @@
CC = clang
CFLAGS = `pkg-config --cflags gtk4 webkit2gtk-5.0`
LIBS = `pkg-config --libs gtk4 webkit2gtk-5.0`
CFLAGS = `pkg-config --cflags gtk4 webkit2gtk-5.0 x11`
LIBS = `pkg-config --libs gtk4 webkit2gtk-5.0 x11`
all:
${CC} -fPIC -g -O3 -o rose *.c $(CFLAGS) $(LIBS)

117
rose.c
View File

@ -1,26 +1,116 @@
#include "rose.h"
#include "config.h"
#include "webview.h"
#include "window.h"
#include <stdio.h>
#include <stdlib.h>
#define MSGBUFSZ 8
#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
guint xid;
void
sigchld(int unused)
{
if (signal(SIGCHLD, sigchld) == SIG_ERR) {
puts("Can't install SIGCHLD handler");
exit(1);
}
while (waitpid(-1, NULL, WNOHANG) > 0)
;
}
void
setatom(int a, const char *v)
{
XChangeProperty(dpy, xid,
atoms[a], atoms[AtomUTF8], 8, PropModeReplace,
(unsigned char *)v, strlen(v) + 1);
XSync(dpy, False);
}
static gboolean
readsock(GIOChannel *s, GIOCondition ioc, gpointer unused)
{
static char msg[MSGBUFSZ];
GError *gerr = NULL;
gsize msgsz;
if (g_io_channel_read_chars(s, msg, sizeof(msg), &msgsz, &gerr) !=
G_IO_STATUS_NORMAL) {
if (gerr) {
fprintf(stderr, "surf: error reading socket: %s\n",
gerr->message);
g_error_free(gerr);
}
return TRUE;
}
if (msgsz < 2) {
fprintf(stderr, "surf: message too short: %lu\n", msgsz);
return TRUE;
}
return TRUE;
}
const char *
getatom(int a)
{
static char buf[BUFSIZ];
Atom adummy;
int idummy;
unsigned long ldummy;
unsigned char *p = NULL;
XSync(dpy, False);
XGetWindowProperty(dpy, xid,
atoms[a], 0L, BUFSIZ, False, atoms[AtomUTF8],
&adummy, &idummy, &ldummy, &ldummy, &p);
if (p)
strncpy(buf, (char *)p, LENGTH(buf) - 1);
else
buf[0] = '\0';
XFree(p);
return buf;
}
static void setup()
{
GIOChannel *gchanin;
sigchld(0);
if (!(dpy = XOpenDisplay(NULL))) {
puts("Can't open default display");
exit(1);
}
atoms[AtomFind] = XInternAtom(dpy, "_ROSE_FIND", False);
atoms[AtomGo] = XInternAtom(dpy, "_ROSE_GO", False);
atoms[AtomUri] = XInternAtom(dpy, "_ROSE_URI", False);
atoms[AtomUTF8] = XInternAtom(dpy, "UTF8_STRING", False);
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, spair) < 0) {
fputs("Unable to create sockets\n", stderr);
spair[0] = spair[1] = -1;
} else {
gchanin = g_io_channel_unix_new(spair[0]);
g_io_channel_set_encoding(gchanin, NULL, NULL);
g_io_channel_set_flags(gchanin, g_io_channel_get_flags(gchanin)
| G_IO_FLAG_NONBLOCK, NULL);
g_io_channel_set_close_on_unref(gchanin, TRUE);
g_io_add_watch(gchanin, G_IO_IN, readsock, NULL);
}
}
static void run(GtkApplication *app)
{
RoseWindow *window = rose_window_new(app);
GtkWidget *webview = rose_webview_new();
if (dark_mode) {
g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", true, NULL);
GdkRGBA color = { 0, 0, 0, 1 };
webkit_web_view_get_background_color(WEBKIT_WEB_VIEW(webview), &color);
}
rose_window_set_webview(window, webview);
rose_window_show(window);
if (homepage)
rose_webview_load_url(WEBKIT_WEB_VIEW(webview), homepage);
xid = rose_window_show(app, window);
setatom(AtomUri, homepage);
}
int main(int argc, char **argv)
@ -30,6 +120,7 @@ int main(int argc, char **argv)
argv++; argc--;
}
setup();
GtkApplication *app = gtk_application_new("org.gtk.rose", G_APPLICATION_NON_UNIQUE);
g_signal_connect(app, "activate", G_CALLBACK(run), NULL);
g_application_run(G_APPLICATION(app), argc, argv);

18
rose.h
View File

@ -1,4 +1,22 @@
#pragma once
#include "window.h"
#include "webview.h"
#include "config.h"
#include <gtk/gtk.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <X11/Xatom.h>
#include <gdk/x11/gdkx.h>
#include <webkit2/webkit2.h>
#include <stdlib.h>
enum { AtomFind, AtomGo, AtomUri, AtomUTF8, AtomLast };
static Atom atoms[AtomLast];
static Display *dpy;
const char* getatom(int a);
static int spair[2];

View File

@ -1,4 +1,5 @@
#include "window.h"
#include "rose.h"
/* #include "gestures.h" */
#include "config.h"
#include "webview.h"
@ -8,6 +9,7 @@
struct _RoseWindow {
GtkApplicationWindow parent_instance;
guint xid;
GtkWindow *window;
WebKitWebView *webview;
GHashTable *action_groups;
@ -66,6 +68,26 @@ static gboolean key_press_callback(RoseWindow *window,
else
gtk_window_fullscreen(GTK_WINDOW(window->window));
break;
case inspector:
puts("wqf");
break;
case search: {
int id = fork();
if (id == 0) {
if (dpy)
close(ConnectionNumber(dpy));
close(spair[0]);
close(spair[1]);
setsid();
char* argument_list[] = {"/bin/sh", "-c", "surf-open", NULL};
execvp("/bin/sh", argument_list);
perror(" failed");
exit(1);
} else {
wait(&id);
webkit_web_view_load_uri(window->webview, getatom(AtomGo));
}
}
}
}
}
@ -93,11 +115,17 @@ static void rose_window_init(RoseWindow *window)
window->window = GTK_WINDOW(gtk_window_new());
}
void rose_window_show(RoseWindow *window)
guint rose_window_show(GtkApplication *app, RoseWindow *window)
{
GtkWidget *w = gtk_window_new();
GtkWidget *w = gtk_application_window_new(app);
window->window = GTK_WINDOW(w);
gtk_window_set_child(GTK_WINDOW(w), GTK_WIDGET(window->webview));
GtkWidget *webview = rose_webview_new();
window->webview = WEBKIT_WEB_VIEW(webview);
if (homepage)
rose_webview_load_url(WEBKIT_WEB_VIEW(webview), homepage);
gtk_window_set_child(GTK_WINDOW(w), GTK_WIDGET(webview));
/* Keyboard shortcuts */
GtkEventController *controller;
@ -106,6 +134,8 @@ void rose_window_show(RoseWindow *window)
gtk_widget_add_controller(GTK_WIDGET(w), controller);
gtk_widget_show(w);
return gdk_x11_surface_get_xid(gtk_native_get_surface(GTK_NATIVE(w)));
}
void rose_window_set_webview(RoseWindow *window, GtkWidget *webview)

View File

@ -1,6 +1,7 @@
#pragma once
#include <gtk/gtk.h>
#include <gdk/x11/gdkx.h>
#include "webview.h"
G_BEGIN_DECLS
@ -10,7 +11,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(RoseWindow, rose_window, ROSE, WINDOW, GtkApplicationWindow)
RoseWindow* rose_window_new();
void rose_window_show(RoseWindow *window);
guint rose_window_show(GtkApplication *app, RoseWindow *window);
gboolean rose_window_close(RoseWindow *window);
void rose_window_set_webview(RoseWindow *window, GtkWidget *webview);