Custom window manager and interaction with applications - x11

I read window managers are responsible for window decorating (title bar, close button, etc.).
So if i can handle, when window is created and modify it somehow (create title bar, close button, etc. for it), how is then application of this window informed, when close button is clicked? There is always some handler in modern toolkits like QT, where i can react to window closing. It must be some way how to tell may application "hey, your window is closing, wanna do something?". I can't find explanation of this behavior.

Related

Win32: how does the OS decide to re-assign focus on window close?

When a focused window is closed, Windows will typically set focus to a different window when possible. I'm trying to figure out what exactly causes this to happen, and in what scenarios does this not occur.
I'm noticing that when some windows are closed, they do not cause the OS to set focus to a new window (eg. Discord, Slack). Discord and Slack are both hidden instead of destroyed on close, but then there are also other windows that when hidden will still cause the OS to set focus to a different window. One such example is with a fresh WPF app and changing the window's Visibility to Collapsed - this causes the window to be hidden, not destroyed, and yet the OS reassigns focus to another window.
What causes some windows when hidden to reassign focus (eg. WPF collapse)? As opposed to applications like Discord/Slack, which are hidden, yet do not reassign OS focus.
It's a multi-step dance of message exchanges, and I no longer have all the details cached in my head. So, generally speaking ...
There's a distinction between activating a window and setting the focus to a window. Windows can get activated in various ways, including a mouse click (either in the client or non-client areas, a keyboard operation, a window being created by a process that currently has "the foreground love", etc.)
A window that's activated can (in effect) accept the focus, reject the focus, or direct the focus to another window (such as a child window like an edit control or button).
A window that doesn't make the effort to direct the focus explicitly when its activated will (likely) end up with the focus by default. That's mostly an artifact of how DefWindowProc handles the relevant messages. But if it's using the dialog manager, then the dialog manager will (if I recall correctly) set the focus to one of the child windows that has the WS_TABSTOP window style.
Imagine a simple text editor application that has a top-level window and one child window that fill the top-level window's client area and hosts the actual editor functionality. In normal behavior, the child window would have the focus whenever the application is in the foreground. But if the top-level window is activated (for something other than a mouse click in the child window's client area), and the top-level window fails to redirect the focus to its child, then it may appear as though nothing has the focus because the window that does have the focus doesn't respond to most kinds of keyboard input.
Key messages involved include: WM_ACTIVATEAPP, WM_NCACTIVATE, WM_ACTIVATE, WM_MOUSEACTIVATE, WM_SETFOCUS, and WM_KILLFOCUS.
Edited to emphasize
what causes the OS to re-assign focus from a window?
In most cases, the OS does not assign focus. It activates and deactivates windows, and the affected applications respond to those events by setting the focus. Applications have a lot of flexibility in how to respond. So if there's an anomaly in where the focus is, it may be more of a question about the behavior of individual applications than about Windows.
It's also possible for a window to have focus but for it to seem as if no window has focus. One case is where the top-level window has focus but doesn't react to the keyboard itself because focus is normally supposed to be assigned to one if its child windows. It's also possible for a hidden window (at least a hidden child window) to have focus if it's not disabled.
Win32's DefWindowProc and dialog-specific APIs, MFC, WPF, and other frameworks generally provide "standard" behavior for handling focus and activation in common cases. But there's a lot of nuance, and there are inherently some differences. For example, WPF applications (if I recall correctly) use windowless child controls, so the traditional behaviors have to be implemented by the framework.

What type of Resource is a Popup Menu in Windows?

I've been researching popup menus (see https://msdn.microsoft.com/en-us/library/windows/desktop/ms647626(v=vs.85).aspx) and a bit confused at what they are behind the scenes.
They act partially like windows, but look like controls. For instance, they pop up above other elements, steal focus, and can go outside their parent container which makes me think they are a type of window. But they pass back an HMENU handle instead of a window handle, and they have no title bar, nor handles, nor show up in the task bar.
If they are a type of control, how can they go outside their parent window?
If they are a type of window, can I use window-specific functions on them? or if they are a control in a new window, is there a way to get a win handle to that new window?
Can I get the location of the popup menu for another application?
Found the answer:
trying to get a handle to a context menu in c++
Looks like a menu is a type of window, that is a child of the desktop window. You can get its window handle with EnumChildWindows on the desktop WinHandle and look for the class name of #32768.
There's more about these reserved system windows here:
About Window Classes | System Classes
A popup menu is a menu, not a window.
A menu merely uses a window for display. A new window is created each time the menu is displayed, and is destroyed afterward. By contrast, the same HMENU can be used to display the menu many times.

Windows. Change drop-down menu position

Is there a way to change the position of the popup menu. With top-level windows I can do it by CBTProc Callback Function and MoveWindow. Can I do the same with menus? Needs to be done so that the pop-up menu is located only in the area of its parent window. Something like a light window manager.
Yes, in a WH_CBT hook callback, you'll be notified with an 'nCode' of HCBT_CREATEWND whenever a menu window is created. Test for the class name, standard menu/submenu windows would have a class name of '#32768'. You can then send a MN_GETHMENU message to the window to find out which menu is about to be activated. But as documented, it is too early to move the window when the notification is received, the menu is not even visible yet, so you might need to sub-class the window and process additional messages.
Note that you don't need a hook to be notified when a menu window is shown, you can put a handler for the WM_ENTERIDLE message, test for 'wParam' to see if a menu caused the message, get the menu window from 'lParam' and again send a 'MN_GETHMENU' to find out the specific menu. It is possible to move the window at this point without further message handling. Just be aware that 'WM_ENTERIDLE' will be called multiple times so you need to keep track of you've already moved a particular window or not.

Is there a way to make changes to the titlebar with GTK2?

I have a desktop application written in Ruby that is using GTK2. It's just a small test application to play with GTK2, but I'm having problems achieving what I want to do. Is there any way using GTK2 to get at the titlebar (apart from setting the title), specifically to either add a button to it (beside the min/max/etc, B in the below diagram) or to add an option to the menu that pops up when you click the icon on the titlebar (A in the below diagram)?
I'm thinking there might not be because GTK is meant to work with many many different window managers, but I just wondered if there was. As a side question, what event does clicking the 'cross' button fire? At the moment if the user clicks that the window disappears but the program doesn't end - I need to capture that event and quit the program.
Thanks for any help, including hitting me over the head and telling me how silly I am.
Note that this is possible in GTK 3.10 and up, by using gtk_window_set_titlebar(). It replaces the window manager's title bar with a custom one. GtkHeaderBar is a good custom title bar class to use.
You can't, however, make it look just like the window manager would, because you won't know which window manager the user is running.
No, the title bar is owned by the window manager and you will typically not have direct access to it.
When the user tries to close the window by clicking the window manager's button, the window will receive the delete event.

Is it possible to create a sub window which will not deactivate the parent?

Normally when creating a sub window (WS_POPUP), the child window will become activate and the parent will become deactivated. However, with menus, both remain active. At least I am assuming the menu is active, it at least has focus.
Example: Click on the file menu in notepad, the menu appears, yet the notepad window still looks active.
Is it possible to mirror this behavior with either a window style or responding to a particular message?
Thanks
Another example: Combo boxes seem to show a subwindow, yet do not deactivate the window. And you can click on that subwindow, while still maintaining an activate main window. Any ideas on how to grab the class /style of that window?
The list dropdown in a combobox is a bit of a hack, it is both a popup and a child window, I can't recommend that approach (Undocumented style combination, and IIRC, it is a bit buggy to do this with a "normal" floating window/toolbar)
This leaves you with two options:
WS_EX_NOACTIVATE (Main window will stay active, floating window is not active)
Handle activate messages (Both windows will look active)
I am surprised that creating a new popup window activates it. Normally you'd need to call SetActiveWindow. However check out WM_ACTIVATE and WM_NCACTIVATE on how to stop the window becoming deactivated.
A fact that a lot of people miss is that windows does not have a separate window manager component :- most of the window management duties are performed by each window - usually in DefWindowProc.
Most window positioning and activation / de-activation is done - ultimately - via a call to SetWindowPos - which always sends a WM_WINDOWPOSCHANGING message allowing the window to have a final say on what happens.
DefWindowProc also activate its own window in response to mouse clicks and so on.
The result of all this is, it is quite possible to create windows that never accept activation - it does require an extensive understanding of what messages and situations might have led to an activation.
Ultimately I can say that it is VERY handy to have a debugging setup configured for remote debugging - so that you can interact with your debugger without effecting the activation state of the system - and hence drop a breakpoint into the window in questions WM_ACTIVATE handler and simply debug any situation leading to an unwanted activation.
If You want to handle keyboard focus as well, it might be trickier - normally focus is given to an activated window - but again its usually the DefWindowProc responsible for assigning both. I just see it dangerous as having one window, still obviously activated, and another with focus. This will confuse any assistive software greatly.
I'd be tempted to perform a message loop level message hook - Similar to IsDialogMessage - to filter keystrokes intended for the popup window.
If you create your popup window with WS_EX_NOACTIVATE it will not be activated by user input (You could still activate it programatically) and therefore your main application window will still remain active.

Resources