aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-11-14 05:48:24 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-14 05:48:24 +0100
commit371e30a0b7b0c2b426452a7be1b0437edb59d98f (patch)
treedb650a3bf393eb5003c25f808e6da4d6f42c9817 /src
parent927168607b202e6f7d2599adda8f0024987ab366 (diff)
Fix f1 grabkey crashing the program if its already bound globally, fix window select on kde
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp78
1 files changed, 69 insertions, 9 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 5a85458..9039058 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
-#include <X11/XKBlib.h>
+#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xrandr.h>
#include <assert.h>
@@ -163,6 +163,61 @@ static void enable_stream_record_button_if_info_filled() {
gtk_widget_set_sensitive(GTK_WIDGET(stream_button), true);
}
+static bool window_has_atom(Display *display, Window window, Atom atom) {
+ Atom type;
+ unsigned long len, bytes_left;
+ int format;
+ unsigned char *properties = nullptr;
+ if(XGetWindowProperty(display, window, atom, 0, 1024, False, AnyPropertyType, &type, &format, &len, &bytes_left, &properties) < Success)
+ return false;
+
+ if(properties)
+ XFree(properties);
+
+ return type != None;
+}
+
+static Window window_get_target_window(Display *display, Window window) {
+ if(window == None)
+ return None;
+
+ Atom wm_state_atom = XInternAtom(display, "_NET_WM_STATE", False);
+ if(!wm_state_atom)
+ return None;
+
+ if(window_has_atom(display, window, wm_state_atom))
+ return window;
+
+ Window root;
+ Window parent;
+ Window *children = nullptr;
+ unsigned int num_children = 0;
+ if(!XQueryTree(display, window, &root, &parent, &children, &num_children) || !children)
+ return None;
+
+ Window found_window = None;
+ for(int i = num_children - 1; i >= 0; --i) {
+ if(children[i] && window_has_atom(display, children[i], wm_state_atom)) {
+ found_window = children[i];
+ goto finished;
+ }
+ }
+
+ for(int i = num_children - 1; i >= 0; --i) {
+ if(children[i]) {
+ Window win = window_get_target_window(display, children[i]);
+ if(win) {
+ found_window = win;
+ goto finished;
+ }
+ }
+ }
+
+ finished:
+ XFree(children);
+ return found_window;
+}
+
/* TODO: Look at xwininfo source to figure out how to make this work for different types of window managers */
static GdkFilterReturn filter_callback(GdkXEvent *xevent, GdkEvent *event, gpointer userdata) {
SelectWindowUserdata *select_window_userdata = (SelectWindowUserdata*)userdata;
@@ -172,11 +227,9 @@ static GdkFilterReturn filter_callback(GdkXEvent *xevent, GdkEvent *event, gpoin
return GDK_FILTER_CONTINUE;
Window target_win = ev->xbutton.subwindow;
-
- if(target_win == None) {
- fprintf(stderr, "Selected the root window! (no window selected)\n");
- return GDK_FILTER_CONTINUE;
- }
+ Window new_window = window_get_target_window(select_window_userdata->display, target_win);
+ if(new_window)
+ target_win = new_window;
int status = XUngrabPointer(select_window_userdata->display, CurrentTime);
if(!status) {
@@ -185,6 +238,14 @@ static GdkFilterReturn filter_callback(GdkXEvent *xevent, GdkEvent *event, gpoin
exit(1);
}
+ if(target_win == None) {
+ show_notification(select_window_userdata->app, "GPU Screen Recorder", "No window selected!", G_NOTIFICATION_PRIORITY_URGENT);
+ GdkScreen *screen = gdk_screen_get_default();
+ GdkWindow *root_window = gdk_screen_get_root_window(screen);
+ gdk_window_remove_filter(root_window, filter_callback, select_window_userdata);
+ return GDK_FILTER_REMOVE;
+ }
+
std::string window_name;
XTextProperty wm_name_prop;
if(XGetWMName(select_window_userdata->display, target_win, &wm_name_prop) && wm_name_prop.nitems > 0) {
@@ -203,7 +264,7 @@ static GdkFilterReturn filter_callback(GdkXEvent *xevent, GdkEvent *event, gpoin
window_name += "(no name)";
}
- fprintf(stderr, "window name: %s\n", window_name.c_str());
+ fprintf(stderr, "window name: %s, window id: %ld\n", window_name.c_str(), target_win);
gtk_button_set_label(select_window_userdata->select_window_button, window_name.c_str());
select_window_userdata->selected_window = target_win;
@@ -1042,6 +1103,7 @@ static void grabkeys(Display *display) {
for(int i = 0; i < 4; ++i)
XGrabKey(display, XKeysymToKeycode(display, XK_F1), Mod1Mask|modifiers[i], root_window, False, GrabModeAsync, GrabModeAsync);
+ XSync(display, False);
XSetErrorHandler(prev_error_handler);
}
@@ -1113,8 +1175,6 @@ static void activate(GtkApplication *app, gpointer userdata) {
GdkWindow *root_window = gdk_get_default_root_window();
//gdk_window_set_events(root_window, GDK_BUTTON_PRESS_MASK);
gdk_window_add_filter(root_window, hotkey_filter_callback, &page_navigation_userdata);
- Bool sup = False;
- XkbSetDetectableAutoRepeat(display, True, &sup);
g_timeout_add(1000, handle_child_process_death, app);