Program stealing focus when clicked
Will Storey <[email protected]> Thu, 14 Jul 2016 17:49:27 -0700
| Newsgroups | gmane.comp.window-managers.ratpoison.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello, I have a program that steals my keyboard focus when I click inside it. I've found most programs don't do this, so this one doing so threw me off. I prefer to change focus through ratpoison. I looked into it a bit and created a patch that stops it happening. I am not sure what I came up with is the best way to resolve the problem though. Background: The program is written using Qt 5. I found if I wrote a small program using Qt 5 that I could reproduce it. Qt 5 itself has code to grab the focus in this condition, not just the specific program I first encountered. I'm not sure if changing Qt 5's behaviour would be better than my patch to ratpoison. It seems to me clicking into a window would give keyboard focus usually anyway (if not using ratpoison that is) so I am wondering if Qt 5 is being too aggressive and I should look at it from that angle. My patch works by keeping track in a variable the last window given focus (by ratpoison). Then when an X FocusIn event happens, I switch focus back if it is not the window ratpoison last gave focus to. This means the problem program grabs focus, but ratpoison immediately grabs it back. From using this patch for a couple days it has worked well. It does seem like it could be hacky though and I'm worried there could be side effects I haven't encountered yet. I've attached it (applies to the git HEAD). I wonder if anyone would have any insight about this issue or any alternative ideas I should look at, or any feedback on my patch. Thanks for reading. _______________________________________________ Ratpoison-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/ratpoison-devel
ratpoison.diff
(text/x-diff, 2.5 KB)
diff --git a/src/events.c b/src/events.c
index 814e1ef..4dde482 100644
--- a/src/events.c
+++ b/src/events.c
@@ -680,15 +680,48 @@ colormap_notify (XEvent *ev)
}
}
+/*
+ * enforce_focussed_window() runs after receipt of a FocusIn event with mode
+ * NotifyNormal.
+ *
+ * It checks if the given window (the one receiving focus) is one ratpoison
+ * focussed. If it is not, it sets focus back to what it should be.
+ *
+ * This is useful in cases where you have programs stealing keyboard focus.
+ */
+static void
+enforce_focussed_window (Window w) {
+ /* If this is a window we focussed, then leave it alone. */
+ if (w == focussed_window)
+ {
+ return;
+ }
+
+ set_window_focus (focussed_window);
+}
+
static void
focus_change (XFocusChangeEvent *ev)
{
- rp_window *win;
+ if (ev == NULL)
+ {
+ return;
+ }
+
+ /* See if we need to revert focus theft. */
+ if (ev->type == FocusIn && ev->mode == NotifyNormal)
+ {
+ enforce_focussed_window (ev->window);
+ return;
+ }
/* We're only interested in the NotifyGrab mode */
- if (ev->mode != NotifyGrab) return;
+ if (ev->mode != NotifyGrab)
+ {
+ return;
+ }
- win = find_window (ev->window);
+ rp_window *win = find_window (ev->window);
if (win != NULL)
{
diff --git a/src/globals.c b/src/globals.c
index 1481a5c..83af975 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -91,6 +91,9 @@ struct numset *rp_frame_numset;
/* The X11 selection globals */
rp_xselection selection;
+/* The window we last gave focus to. */
+Window focussed_window = 0;
+
static void
x_export_selection (void)
{
@@ -253,6 +256,7 @@ void
set_rp_window_focus (rp_window *win)
{
PRINT_DEBUG (("Giving focus to '%s'\n", window_name (win)));
+ focussed_window = win->w;
XSetInputFocus (dpy, win->w,
RevertToPointerRoot, CurrentTime);
}
@@ -261,6 +265,7 @@ void
set_window_focus (Window window)
{
PRINT_DEBUG (("Giving focus to %ld\n", window));
+ focussed_window = window;
XSetInputFocus (dpy, window,
RevertToPointerRoot, CurrentTime);
}
diff --git a/src/globals.h b/src/globals.h
index 1fb7e0f..7dc5483 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -207,6 +207,9 @@ void set_selection (char *txt);
void set_nselection (char *txt, int len);
char *get_selection (void);
+/* The window we last gave focus to. */
+extern Window focussed_window;
+
/* Wrapper font functions to support Xft */
void rp_draw_string (rp_screen *s, Drawable d, int style, int x, int y, char *string, int length);