What are the SDL_WindowFlags SDL_WINDOW_INPUT_FOCUS and SDL_WINDOW_MOUSE_FOCUS used for ?
If I am not mistaken SDL_WINDOW_INPUT_GRABBED indicates which window is receiving inputs, if any. But I simply cannot see what the two other flags mean. I checked SDL_video.h to see if I could get more information, but what I read didn't help :
SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */
SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */
SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */
I don't see the difference between "window has grabbed input focus" and "indow has input focus".
Is INPUT_FOCUS only for keyboard input and MOUSE_FOCUS for mouse input ? In that case, why would INPUT_GRABBED not be a combination of these two ?
Furthermore, is it possible to have a window with mouse focus and another with "input" focus (whatever "input" means here, except "mouse"), or something similar ?
I just realised that SDL_WINDOW_INPUT_GRABBED was not what I thought it was. It is set with SDL_SetWindowGrab and forces the mouse to stay inside the window (so the window has both mouse and keyboard focus).
The INPUT_FOCUS flag indicates whether the window is active or not (has keyboard input, and probably other controller inputs too).
The MOUSE_FOCUS flag indicates whether the mouse is hovering over the window, even if the window is not active.
Related
For some fun and self-education, I'm tinkering with writing my own X11 toolkit. Here's something that's stumping me.
I have a traditional combo box display element, a typical combo box with a dropdown popup list, like all popular toolkits have.
For the dropdown popup list, I'm creating a new window, a child of the root window, appropriately positioned below the main combo-box display element.
The dropdown popup list is a window in its own full right, that implements keyboard-based navigation, to select the individual entries in the dropdown list.
So, I'm using SetInputFocus to set the input focus to the popup after it opens.
What I find is that when I do that, the window manager then redraws the frame of the main window to indicate that it no longer has input focus. Which is technically true, but I don't see the same results with the more mainstream toolkits, where, in the comparable situation, the main window's frame shows that it still has input focus.
For the pop-up window, in addition to setting override-redirect, I'm also doing everything I can think of, to tell the window manager what's going on: setting the window group leader ID in the popup window's WM_HINTS, setting WM_TRANSIENT_FOR, and setting _NET_WM_WINDOW_TYPE to _NET_WM_WINDOW_TYPE_COMBO; none of that seems to work (I verified that the properties are approriately set, via xprop).
It seems like I have to keep the input focus in the combo box window, and forward keypress and keyrelease events to the display elements in the dropdown popup, which feels clunky. Am I overlooking some property that would tell the window manager that the popup's input focus is linked to the main window's (besides the ones that I've mentioned), that would keep the main window's frame drawn to show that it has input focus, when the input focus is actually in the popup?
Most X11 override-redirect exclusive popup windows (menus, combo boxes, ...) grab the keyboard and/or pointer with either passive or active grab.
See XGrabKey, XGrabKeyboard, XGrabButton, XGrabPointer in the X11 programming manual.
Or maybe don't, because the manual is totally unclear about what the heck these functions are and how they can be used. Search the interwebs for usage examples, probably in other widget libraries. Unfortunately I don't know of a simple informative example offhand.
It is not necessary to call XSetInputFocus at all because all keyboard and/or pointer events are reported to the grabbing clients.
I have a semi-transparent form (using AlphaBlend) that acts as an overlay. For the user to still be able to interact with the window below I have set WS_EX_NOACTIVATE on my form so all right and left clicks go through to the other window.
However I have a few clickable labels on my form. Clicking those and performing the appropriate action works fine since despite the WS_EX_NOACTIVATE flag the OnClick methods are called, but the click will (obviousely) also propagate to the other window, which I do not want in this case.
So, does anyone know how to "stop" the click being sent through to the window below in case I already handled it in my form ? Basically I would like being able to chose whether the click "belongs to me" and does not get propagated or whether the window below mine receives it.
As Rob explained, WS_EX_NOACTIVATE is not relevant here. Most likely you used WS_EX_TRANSPARENT and that made your window transparent to mouse clicks.
To get finer grained control of mouse click transparency, handle the WM_NCHITTEST message in your top level window. Return HTTRANSPARENT for regions that you want to be "click through". Otherwise return, for example, HTCLIENT.
Wm_ex_NoActivate should be irrelevant here. That just controls whether your window receives the input focus. Indeed, if you start with a scratch program and do nothing but change the extended window style, you'll see that when you click within the bounds of that program's window, the clicks are handled in the usual way, except that the window is never activated; programs behind that window do not receive any click events.
Therefore, to make your label controls eat click events instead of forwarding them to the windows behind them, you need to find out what you did to make them start forwarding those messages and simply stop doing that, whatever that is.
A program has called XGrabKey() to make a hotkey.
The user presses that key combination (while another window is focused).
The program receives control to do something in response to the key combination. Meanwhile, the program has been temporarily focused (because of the effects of XGrabKey (see man XGrabKey, man XGrabKeyboard)).
I want the program to create a synthetic X event (a keypress or mouse click) to the originally focused window. In some cases this means I need to focus that window before sending it the event (Firefox ignores synthetic events when it is not focused), which means I need to know which window it is. How can I find out which window it is?
Wait for the next FocusOut event, verify that the mode is set to NotifyUngrab, get the focus with XGetInputFocus(), and send away your synthetic events.
We know that Static Control in Windows does not receive input focus. But since Static Control in Windows is just a child window, according to what I understand so far, any window should be given input focus when we click on it. So how does Static control achieve this effect of rejecting input focus? I suspect it has special processing in its WM_SETFOCUS handler that yields the input focus to its parent window. However, I've done some tests and it seems that the child window really does not receipt any WM_SETFOCUS at all i.e. Windows never really tried to give input focus to the static control at all.
I've read the msdn on input focus and there is nothing related to how Windows allocate focus for static control. Can anyone explain how Static Control is made not to have input focus?
The static control returns HTTRANSPARENT from its WM_NCHITTEST handler. That causes the click to go directly to the underlying window (which is the parent). The WM_MOUSEACTIVATE and WM_*BUTTONCLICK and other magic eventually leads to an activation and SetFocus.
Context:
I use glfw under xmonad. Glfw apparently sets the window title after creating the window, thus not allowing xmonad to properly handle it. I want to modify the glfw source so that I can set the window title before creating the window.
Problem:
So I download glfw-2.6, and I look into lib/x11/x11_window.c ; the lines causing the trouble are:
// Create a window
_glfwWin.Win = XCreateWindow(
_glfwLibrary.Dpy,
RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ),
0, 0, // Upper left corner
_glfwWin.Width, _glfwWin.Height, // Width, height
0, // Borderwidth
_glfwWin.VI->depth, // Depth
InputOutput,
_glfwWin.VI->visual,
CWBorderPixel | CWColormap | CWEventMask,
&wa
);
Followed sometime later by:
_glfwPlatformSetWindowTitle( "GLFW Window" );
where
void _glfwPlatformSetWindowTitle( const char *title )
{
// Set window & icon title
XStoreName( _glfwLibrary.Dpy, _glfwWin.Win, title );
XSetIconName( _glfwLibrary.Dpy, _glfwWin.Win, title );
}
Now, if I tr yto move the glfwPlatformSetWindowTitle call before the CreateWindow call, I get a segfault -- as I should, since _glfwWin.win would not be defined.
I don't know how to solve this problem since to set the window title, I need _glfwWin.Win to be initialized, but to initialize it, I need to create the window.
Thus, I ask: in X11, what is the proper way to set the window title before creating the window?
Thanks!
This is not possible in X11, but also not necessary for stuff to work. There must be a bug somewhere causing the symptoms you're seeing. The window title is just a property on the window, and properties can't exist until there's a window for them to be on.
You say "not allowing xmonad to properly handle it" which implies it isn't coping with changes to the name; window managers absolutely must handle setting the title at any time, including changing the title long after a window is created.
What the spec says (http://www.x.org/docs/ICCCM/icccm.pdf) is:
"The window manager will examine the contents of these properties when the window makes the
transition from the Withdrawn state and will monitor some properties for changes while the window is in the Iconic or Normal state."
The "transition from the Withdrawn state" is the point where glfw calls XMapWindow(). At that point, the window will remain unmapped but the WM will receive a MapRequest. The WM would then read properties and such and then map the window. All window managers I've ever seen also handle later changes to the property because changing the window title is pretty normal. For example web browsers the page title on every url.
If xmonad doesn't handle changes maybe it at least waits for the map, so maybe you just need to set title before XMapWindow(). Really all setup should be done before MapWindow though only a few properties are required to be before it by the specs. The props that must be before it generally can't be changed without unmapping.
Incidentally, _glfwPlatformSetWindowTitle won't work for anything but Latin-1. The modern way to do it is to set _NET_WM_NAME and _NET_WM_ICON_NAME with XChangeProperty() (setting the old Latin-1 WM_NAME is fine too but only as a fallback).