summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfalkTX <falktx@gmail.com>2015-10-14 02:52:12 +0200
committerfalkTX <falktx@gmail.com>2015-10-14 02:52:12 +0200
commitb48a3437be61dbb9a0a360540ef5011b9d862171 (patch)
treeb452ce2778c00cf3063c5bf715531dd85078c580
parent7365b4886cca1c21d540d581f70b80ee9ef4fe92 (diff)
Send ignored keys to *top-most* parent window, fix feedback loop
-rw-r--r--dgl/src/pugl/pugl_internal.h1
-rw-r--r--dgl/src/pugl/pugl_x11.c37
2 files changed, 34 insertions, 4 deletions
diff --git a/dgl/src/pugl/pugl_internal.h b/dgl/src/pugl/pugl_internal.h
index 3ca59ca7..a97e6196 100644
--- a/dgl/src/pugl/pugl_internal.h
+++ b/dgl/src/pugl/pugl_internal.h
@@ -59,6 +59,7 @@ struct PuglViewImpl {
PuglInternals* impl;
PuglNativeWindow parent;
+ PuglNativeWindow topparent;
PuglContextType ctx_type;
uintptr_t transient_parent;
diff --git a/dgl/src/pugl/pugl_x11.c b/dgl/src/pugl/pugl_x11.c
index 7066351b..0d59c099 100644
--- a/dgl/src/pugl/pugl_x11.c
+++ b/dgl/src/pugl/pugl_x11.c
@@ -460,9 +460,34 @@ dispatchKey(PuglView* view, XEvent* event, bool press)
}
send_event:
- if (view->parent) {
- event->xany.window = view->parent;
- XSendEvent(view->impl->display, view->parent, True, press ? KeyPressMask : KeyReleaseMask, event);
+ if (view->parent != 0) {
+ if (view->topparent == 0) {
+ uint nchildren;
+ Window root, newparent, oldparent, *children;
+
+ oldparent = view->topparent = view->parent;
+ while (XQueryTree(view->impl->display, oldparent, &root, &newparent, &children, &nchildren) != 0) {
+ if (nchildren == 0 || children == NULL) {
+ break;
+ }
+ XFree(children);
+ if (newparent == 0 || newparent == root) {
+ break;
+ }
+
+ // FIXME: this needs a proper check for desktop-style window
+ if (newparent < 0x6000000 &&
+ XGetTransientForHint(view->impl->display, oldparent, &newparent) == 0) {
+ break;
+ }
+
+ view->topparent = oldparent = newparent;
+ }
+ }
+
+ event->xkey.time = 0; // purposefully set an invalid time, used for feedback detection
+ event->xany.window = view->topparent;
+ XSendEvent(view->impl->display, view->topparent, False, NoEventMask, event);
}
}
@@ -492,7 +517,11 @@ puglProcessEvents(PuglView* view)
break;
}
- if (event.xany.window != view->impl->win) {
+ if (event.xany.window != view->impl->win &&
+ (view->parent == 0 || event.xany.window != (Window)view->parent)) {
+ continue;
+ }
+ if ((event.type == KeyPress || event.type == KeyRelease) && event.xkey.time == 0) {
continue;
}