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
|
#define MODKEY GDK_CONTROL_MASK
|
||||||
|
|
||||||
static Key keys[] = {
|
static Key keys[] = {
|
||||||
{ MODKEY, GDK_KEY_h, goback },
|
{ MODKEY, GDK_KEY_h, goback },
|
||||||
{ MODKEY, GDK_KEY_l, goforward },
|
{ MODKEY, GDK_KEY_l, goforward },
|
||||||
{ MODKEY, GDK_KEY_y, copy_url },
|
{ MODKEY, GDK_KEY_y, copy_url },
|
||||||
{ MODKEY, GDK_KEY_p, paste_url },
|
{ MODKEY, GDK_KEY_p, paste_url },
|
||||||
{ 0, GDK_KEY_F11, fullscreen }
|
{ 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/gdk.h>
|
||||||
#include <gdk/gdkkeysyms.h>
|
#include <gdk/gdkkeysyms.h>
|
||||||
|
|
||||||
#define NONE 4
|
#define SHIFT GDK_SHIFT_MASK
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned modkey;
|
unsigned modkey;
|
||||||
|
@ -16,5 +16,7 @@ enum {
|
||||||
goforward,
|
goforward,
|
||||||
copy_url,
|
copy_url,
|
||||||
paste_url,
|
paste_url,
|
||||||
fullscreen
|
fullscreen,
|
||||||
|
inspector,
|
||||||
|
search
|
||||||
};
|
};
|
||||||
|
|
4
makefile
4
makefile
|
@ -1,6 +1,6 @@
|
||||||
CC = clang
|
CC = clang
|
||||||
CFLAGS = `pkg-config --cflags gtk4 webkit2gtk-5.0`
|
CFLAGS = `pkg-config --cflags gtk4 webkit2gtk-5.0 x11`
|
||||||
LIBS = `pkg-config --libs gtk4 webkit2gtk-5.0`
|
LIBS = `pkg-config --libs gtk4 webkit2gtk-5.0 x11`
|
||||||
|
|
||||||
all:
|
all:
|
||||||
${CC} -fPIC -g -O3 -o rose *.c $(CFLAGS) $(LIBS)
|
${CC} -fPIC -g -O3 -o rose *.c $(CFLAGS) $(LIBS)
|
||||||
|
|
117
rose.c
117
rose.c
|
@ -1,26 +1,116 @@
|
||||||
#include "rose.h"
|
#include "rose.h"
|
||||||
#include "config.h"
|
|
||||||
#include "webview.h"
|
#define MSGBUFSZ 8
|
||||||
#include "window.h"
|
#define LENGTH(x) (sizeof(x) / sizeof(x[0]))
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
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)
|
static void run(GtkApplication *app)
|
||||||
{
|
{
|
||||||
RoseWindow *window = rose_window_new(app);
|
RoseWindow *window = rose_window_new(app);
|
||||||
GtkWidget *webview = rose_webview_new();
|
|
||||||
|
|
||||||
if (dark_mode) {
|
if (dark_mode) {
|
||||||
g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", true, NULL);
|
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);
|
xid = rose_window_show(app, window);
|
||||||
rose_window_show(window);
|
setatom(AtomUri, homepage);
|
||||||
|
|
||||||
if (homepage)
|
|
||||||
rose_webview_load_url(WEBKIT_WEB_VIEW(webview), homepage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@ -30,6 +120,7 @@ int main(int argc, char **argv)
|
||||||
argv++; argc--;
|
argv++; argc--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setup();
|
||||||
GtkApplication *app = gtk_application_new("org.gtk.rose", G_APPLICATION_NON_UNIQUE);
|
GtkApplication *app = gtk_application_new("org.gtk.rose", G_APPLICATION_NON_UNIQUE);
|
||||||
g_signal_connect(app, "activate", G_CALLBACK(run), NULL);
|
g_signal_connect(app, "activate", G_CALLBACK(run), NULL);
|
||||||
g_application_run(G_APPLICATION(app), argc, argv);
|
g_application_run(G_APPLICATION(app), argc, argv);
|
||||||
|
|
18
rose.h
18
rose.h
|
@ -1,4 +1,22 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "window.h"
|
||||||
|
#include "webview.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <gtk/gtk.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 <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 "window.h"
|
||||||
|
#include "rose.h"
|
||||||
/* #include "gestures.h" */
|
/* #include "gestures.h" */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "webview.h"
|
#include "webview.h"
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
struct _RoseWindow {
|
struct _RoseWindow {
|
||||||
GtkApplicationWindow parent_instance;
|
GtkApplicationWindow parent_instance;
|
||||||
|
|
||||||
|
guint xid;
|
||||||
GtkWindow *window;
|
GtkWindow *window;
|
||||||
WebKitWebView *webview;
|
WebKitWebView *webview;
|
||||||
GHashTable *action_groups;
|
GHashTable *action_groups;
|
||||||
|
@ -66,6 +68,26 @@ static gboolean key_press_callback(RoseWindow *window,
|
||||||
else
|
else
|
||||||
gtk_window_fullscreen(GTK_WINDOW(window->window));
|
gtk_window_fullscreen(GTK_WINDOW(window->window));
|
||||||
break;
|
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());
|
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);
|
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 */
|
/* Keyboard shortcuts */
|
||||||
GtkEventController *controller;
|
GtkEventController *controller;
|
||||||
|
@ -106,6 +134,8 @@ void rose_window_show(RoseWindow *window)
|
||||||
gtk_widget_add_controller(GTK_WIDGET(w), controller);
|
gtk_widget_add_controller(GTK_WIDGET(w), controller);
|
||||||
|
|
||||||
gtk_widget_show(w);
|
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)
|
void rose_window_set_webview(RoseWindow *window, GtkWidget *webview)
|
||||||
|
|
3
window.h
3
window.h
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/x11/gdkx.h>
|
||||||
#include "webview.h"
|
#include "webview.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
@ -10,7 +11,7 @@ G_BEGIN_DECLS
|
||||||
G_DECLARE_FINAL_TYPE(RoseWindow, rose_window, ROSE, WINDOW, GtkApplicationWindow)
|
G_DECLARE_FINAL_TYPE(RoseWindow, rose_window, ROSE, WINDOW, GtkApplicationWindow)
|
||||||
|
|
||||||
RoseWindow* rose_window_new();
|
RoseWindow* rose_window_new();
|
||||||
void rose_window_show(RoseWindow *window);
|
guint rose_window_show(GtkApplication *app, RoseWindow *window);
|
||||||
gboolean rose_window_close(RoseWindow *window);
|
gboolean rose_window_close(RoseWindow *window);
|
||||||
|
|
||||||
void rose_window_set_webview(RoseWindow *window, GtkWidget *webview);
|
void rose_window_set_webview(RoseWindow *window, GtkWidget *webview);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user