Add support for xatom search action
This commit is contained in:
parent
b0f9f5f421
commit
035a345158
12
config.h
12
config.h
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
4
makefile
4
makefile
|
@ -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
117
rose.c
|
@ -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
18
rose.h
|
@ -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];
|
||||
|
|
36
window.c
36
window.c
|
@ -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)
|
||||
|
|
3
window.h
3
window.h
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user