Hacker News new | ask | show | jobs
by Stratoscope 836 days ago
Traditional Microsoft Windows apps do have one oddity here: the "client" and "non-client" areas.

The non-client area included stuff like the title bar, min/max/close buttons and system menu icon, and resizing borders.

The client area was where your app would put its content, including any child windows like buttons and list boxes.

Many of the window messages for the client area had corresponding non-client messages, for example WM_PAINT and WM_NCPAINT. All of these messages would arrive in your GetMessage/DispatchMessage loop, but you would generally ignore the WM_NC versions and DispatchMessage would send them to the Windows code for default processing.

OS/2 Presentation Manager took a more elegant approach here (but probably slower). You had one main window and everything inside it - both "client" and "non-client" stuff - was child windows.

So you just had one set of messages for everything, no WM_NCxxxx messages at all. The client area was a child window, with other child windows for the non-client doodads.

6 comments

The application not being forced to handle the title bar and its buttons, but getting the default one for free. I wonder when the GNOME/mutter people will discover such a novel concept (regarding Wayland).
They are very intentionally choosing to put that responsibility in the client. It is very irritating and their choice (as opposed to other compositors that support the decoration protocols) is one of the bigger sources of Wayland fragmentation.
Honestly I haven’t touched Linux in a desktop sense in years, and the drama around Wayland/window trim makes me miss it lol
Windows works just like GNOME here: decorations are client side and are drawn in user32. dll.
Um not really.If the application gets stuck, Windows Desktop Window Manager slaps its own titlebar on top of the window, ignoring all client decoration. You can still move it or close it.

On GNOME, if the application gets stuck you have to kill it by other means.

Oh god, WM_PAINT. that takes me back. I'm not convinced that css is better, given how many lives were wasted trying to get a responsive 3 column view to work before flex box, but here we are.
And something behind still needs WM_PAINT to display the thing styled by CSS... at least if it's displayed on a Windows machine
The distinction probably helped with management of busy or hung processes which didn't process window messages. Window system internals probably yank the non-client messages from the queue, and do the default processing to make window movement and closing with X button work reliably.
Yeah, this was a big problem with OS/2 and why I don't like to use client side decorations on Linux.
It's interesting that someone already tried that long before Wayland and Gnome, with the predictable result...
Non-client area also applies to controls (non-top-level windows) as well. For example, the border on a text box is part of the nonclient area of that window.
One object receiving different messages for painting its innards vs its chrome isn't particularly ugly. Most apps don't want to customize the chrome so they'll let the base class handle those messages, but the option is there.

Windows is kinda smalltalk-like in its window message system.

Now that modern browsers draw tabs and other stuff in their title bar area, does that mean that they actually handle WM_NCxxxx messages?
Those are most likely windows which have been created without window chrome. The Win32 CreateWindowEx() function has style flags which allows all sorts of modifications down to "just give me a featureless rectangle to draw into". That's a really nice thing about the Win32 window system, it gives you a fully featured default window and then you can gradually override the defaults as needed.
I think they actually don't use that flag but use this function here: https://learn.microsoft.com/en-us/windows/desktop/api/Dwmapi...

The feature is from Windows Vista and it is still the basis of acyrilic effects on 11. The feature is explained in this page: https://learn.microsoft.com/en-us/windows/win32/dwm/customfr...