Thread: [Java-gnome-developer] Unable to Activate an hidden Window from a third party library callback meth
Brought to you by:
afcowie
From: Frédéric L. <lab...@gm...> - 2010-04-12 21:38:45
|
Hi ! I'm working on a project which deals with building a Clipboard History tool. I've built the tool out of the following components: + a java-gnome GTK app (developed by myself). (widget tree detailed at the end of this post) + JXGrabkey (native shared library+ JNI Java bindings) + a custom native shared library used to monitor clipboard content (no implications with this post) I use JXGrabkey to register a global/system wide X11 hotkey in order to hide/to put to front the application main window. When the defined hotkey is pressed then released the JXGrabkey java binding is called and calls a supplied java callback which I implemented as follow public static void hotkeyCallBack() { clippo.toggleMainWindow(); } where clippo is an instance of my app Class with the toggleMainWindow implemented as follow : void toggleMainWindow () { if (isMainWindowVisible || isMainWindowMinimized) { mainWindow.hide(); } else { isMainWindowVisible=true; isMainWindowMinimized=false; mainWindow.grabFocus(); //clipItemListView.grabFocus(); } } This call back is not executed in the main Thread but in a Thread initiated by JXGrabKey. It works fine as the window is successfully hidden or shown but I experience the following behavior : When the window is show (hidden state to visible), the window stays unselected and the keypress are still sent to whatever window I was using prior using the hotkey. For example while a Firefox window is opened, active and has focus (I can scroll page using keyboard arrows), I press the proper hotkey and my main Window is shown. This window has its top level set to true and it is centered with a WindowPosition.MOUSE so the Window is on top of the display. I tried using the grabFocus on my Window instance,the tree view instance or the textinput instance, aleas! the window keeps staying unselected/unactive (its title bar colour indicates me it is unselected). I move arrows the current window is still the browser one. If I click my window comes active. (I want the user to be able to do everything without mouse interactions). Am I doing something the Wrong way. I've been browsing API javadocs without finding Window.setActive or obvious workaround. Did I miss a point ? Am I doing something the wrong way ? Are my troubles due to the TreadAwareness design of Java-gnome ? Any ideas to implement the described behavior with a different code design ? Fred L. Widget Tree : Window (mainWindow) VBox Treeview Trextview |
From: Andrew C. <an...@op...> - 2010-04-12 22:45:58
|
On Mon, 2010-04-12 at 23:38 +0200, Frédéric LABBE wrote: > > I'm working on a project which deals with building a Clipboard History > tool. Hey, cool. Neat. > I use JXGrabkey to register a global/system wide X11 hotkey in order > to hide/to put to front the application main window. So the question seems to be how to properly implement a desktop wide hotkey. That's interesting. The window manager gets away with this, obviously, but the question is how other apps can register such a thing. I've noticed a few applications that seem to do so. Hamster Applet's preference dialog has a "global hotkey" Entry which contains (on my system anyway) "<Super>+H", for example. Maybe we could have a look at their code (which is Python, I'm afraid) to see what they're doing. > void toggleMainWindow () { I have something similar in Slashtime. Keeping the state variables about whether you are minimized or not is trickier than it should be; I think the compositors of the last few years have messed with (ie) the VisibilityEvents. > This call back is not executed in the main Thread but in a Thread > initiated by JXGrabKey. > It works fine as the window is successfully hidden or shown Oh, it works, ok :) > When the window is show (hidden state to visible), the window stays > unselected and the keypress are still > sent to whatever window I was using prior using the hotkey. Yeah, Widget's grabFocus() is about focus within the application. It's a lot harder to force the window manager to do something if you're not the currently active application. Did you try Window's present()? http://java-gnome.sourceforge.net/4.0/doc/api/org/gnome/gtk/Window.html#present() > Did I miss a point ? Am I doing something the wrong way ? I don't think so, but you're outside the boundaries of a single application, so we need to work cooperatively with the window manager. There's only so much we can do there; getting focus behaviour right between applications (ie, preventing focus stealing) has taken the window-manager people years to get right. > Are my troubles due to the TreadAwareness design of Java-gnome ? No, I don't think so (ie, it's working, not crashing or blocking, so you're probably ok). But the fact you're having to go straight to X (instead of letting GDK do it for you) is a very bad sign; that usually causes problems. > > Any ideas to implement the described behavior with a different code > design ? Not off hand, but then I've never tried to come up with a global hot key. If I had to guess, the right question to ask is "what's the GNOME way to take a keypress globally", perhaps http://live.gnome.org/ControlCenter/ApplicationDefinedKeybindings Once we know what we're doing, then we can figure out what to add to java-gnome if we need to. AfC Sydney -- Andrew Frederick Cowie Operational Dynamics is an operations and engineering consultancy focusing on IT strategy, organizational architecture, systems review, and effective procedures for change management: enabling successful deployment of mission critical information technology in enterprises, worldwide. http://www.operationaldynamics.com/ Sydney New York Toronto London |
From: F.L. <lab...@gm...> - 2010-04-12 23:50:23
|
Andrew Cowie <andrew@...> writes: Thank you for your quick reply. > So the question seems to be how to properly implement a desktop wide > hotkey. That's interesting. I had a look at Parcellite (Clipboard manager written in C) to implement that feature quickly and found JXGrabkey implementing it similary; Parcelite application don't have the described problem as its history gui is a popup menu linked to a status icon and clipboard entries are listed as menu items. What I try to do : A) I need to popup a list view on a key, list items can be filtered by typing wildcards in a textview. B) use arrow key (prefered) or mouse to select history entry, put it in the clipboard, hide the window containing the listview C) and try to paste it back in the former active window. XSendKey ? C) due to B) out of scope for the moment. > > The window manager gets away with this, obviously, but the question is > how other apps can register such a thing. I've noticed a few > applications that seem to do so. Hamster Applet's preference dialog has > a "global hotkey" Entry which contains (on my system anyway) > "<Super>+H", for example. > > Maybe we could have a look at their code (which is Python, I'm afraid) > to see what they're doing. OK I'll have a look. > Did you try Window's present()? Yes I did, no result. . > But the fact you're having to go straight to X (instead of letting GDK > do it for you) is a very bad sign; that usually causes problems. :)( I'am currently doing some painful experimentations X11/C. I was naively hoping to stay in the good old safe Java world :) F.L. |
From: Andrew C. <an...@op...> - 2010-04-14 03:05:07
|
On Mon, 2010-04-12 at 23:44 +0000, F.L. wrote: > A) I need to popup a list view on a key, list items can be filtered > by typing wildcards in a textview. Easy. Do you know about TreeModelFilter? http://java-gnome.sourceforge.net/4.0/doc/api/org/gnome/gtk/TreeModelFilter.html You add an Entry where user types. You write an Entry.Changed handler; there you call TreeModelFilter's refilter(), then in the TreeModelFilter.Visible you check against the current text of the Entry. > B) use arrow key (prefered) or mouse to select history entry, Yup. You'll want TreeSelection's setMode() to SelectionMode.SINGLE http://java-gnome.sourceforge.net/4.0/doc/api/org/gnome/gtk/TreeSelection.html#setMode(org.gnome.gtk.SelectionMode) > put it in the clipboard, Easy, Clipboard's setText(), presumably http://java-gnome.sourceforge.net/4.0/doc/api/org/gnome/gtk/Clipboard.html [there's a fair bit more complexity available in GtkClipboard we could expose, but no one has needed it yet] http://library.gnome.org/devel/gtk/stable/gtk-Clipboards.html http://www.freedesktop.org/wiki/Specifications/clipboards-spec > hide the window containing the listview That's your business, but Widget's hide(). > C) and try to paste it back in the former active window. huh? Yikes. You're telling another application to do something? That's not going to be easy. > XSendKey ? That'd just be a simulated keystroke one key at a time. That's probably not a good idea. I can see the effect you're going for; within your own application that'd be do-able. But one app telling another app what to do (outside of, say, libnotify or DBus or...) is really sketchy. Heck, only the window manager can really tell other apps what to do, and even then it's only size and visibility. But in any case, the task right now is to keep a journal of clipboard changes and to be able to replay the selected clipboard item back into the clipboard on request. Even if you can't force paste elsewhere, getting the item onto the clipboard will get you most of the way to what you want. AfC Sydney |