Hacker News new | past | comments | ask | show | jobs | submit login
A peculiarity of the X Window System: Windows all the way down (utcc.utoronto.ca)
194 points by ingve 5 months ago | hide | past | favorite | 122 comments



This is not unique to X. Windows for example uses the same kind of "HWND" object for buttons as for top-level windows. Windows doesn't have the same client/server overhead as X though.

In Qt, there is an option to use either native windows for individual widgets or "alien" windows, in which only the top level widget is a native window - https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-....


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.


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...


Good further reading on this change is "Windowless controls are not magic"[1] from Raymond Chen, and the followup "Windows are not cheap objects"[2]. It's a fascinating tradeoff space. I think fine-grained windows worked reasonably well on limited hardware but did not scale to super-rich applications like web browsers, or a more sophisticated imaging model where widgets need to be composited with alpha-transparency.

[1]: https://devblogs.microsoft.com/oldnewthing/20050211-00/?p=36...

[2]: https://devblogs.microsoft.com/oldnewthing/20050315-00/?p=36...


90s apps used these Windows handle controls and it was not a performance problem. On computers 100 slower than today and with 1000 times less memory.

BTW, the current Windows Task Manager still shows the total HANDLE count on the CPU page.

They were not used in apps with complex UIs because native controls were hard to skin and didn't work very well when their size was very small (as complex UIs tend to need)


> 90s apps used these Windows handle controls and it was not a performance problem.

That depends on the overhead per window. Microsoft Windows could use nested windows because it had separate Graphics objects to store such things as the current drawing pen, its position and the current font to use for drawing (https://learn.microsoft.com/en-us/windows/win32/api/gdiplusg...)

In comparison, on the classic Mac every window had a GrafPort that defined a boundary region, a clipping region, the current pen position, size, drawing pattern, etc.

The Mac could have such heavy-weight window objects because it didn’t nest windows. Instead, each window had a single list of controls that were much lighter-weight.

my gut feeling says separating the drawing state from windows as in MS Windows is the better choice, but I also think having separate entities called “windows” and “controls” as on the Mac is the better choice.

(its documentation is ‘less than stellar’, but it appears GrafPort still exists: https://developer.apple.com/documentation/applicationservice...)


> (its documentation is ‘less than stellar’, but it appears GrafPort still exists:

GrafPort is part of QuickDraw, almost all of which was removed in 64-bit macOS. (A handful of QuickDraw functions survive, but they can't actually be used to do drawing, just to manipulate Point/Region/etc data structures.)

From what I understand, this struct/typedef remains in the headers to help with compiling legacy code–but all the APIs which take it as an argument have been removed, so it is essentially a useless vestige.


> my gut feeling says separating the drawing state from windows as in MS Windows is the better choice, but I also think having separate entities called “windows” and “controls” as on the Mac is the better choice.

I like to sum up the difference between Mac and Windows thusly. Probably glossing over a bunch of stuff but still:

* Steve Jobs toured Xerox and came away with an idea, and a fairly shallow one -- the windowed, mouse-driven, document-centric interface. This is what he then had his team implement in the Lisa and Mac. As implementations go, it was really good and it looked good, but it was really procedural Pascal code beneath. (You had to handle window moving and resizing yourself in early Mac OS. There were library functions to help, but you had to code all that into your application's main loop.)

* Microsoft, at right about the same time, was hiring guys out of Xerox PARC itself -- guys like Charles Simonyi -- and they brought with them a whole passel of ideas, not just concerning interfaces but also software design, things like objects and message-passing. That's why Windows could do things like handle the move and resize drag actions, and then just post WM_MOVE or WM_RESIZE to the target window. Windows were objects -- members of classes, even, and could receive messages.

Granted, Windows couldn't run in 128K -- and Jobs would pivot completely with NeXT and deliver an object-oriented desktop based on Smalltalk grafted onto C (Objective-C), but initially it seems Apple were trying to build a cheaper, more user friendly Xerox Star and Microsoft were trying to get as much of the Smalltalk environment as would fit in a PC without requiring devs to learn a new language.


FWIW, Steve agreed with your assessment. One of my favorite Jobs quotes:

I had three or four people who kept bugging me that I ought to get my rear over to Xerox PARC and see what they were doing. And so I finally did. I went over there. And they were very kind and they showed me what they were working on. And they showed me really three things, but I was so blinded by the first one that I didn’t even really see the other two. One of the things they showed me was object-oriented programming. They showed me that, but I didn’t even see that. The other one they showed me was really a network computer system. They had over a hundred Alto computers, all network using email, et cetera, et cetera. I didn’t even see that.

I was so blinded by the first thing they showed me, which was the graphical user interface. I thought it was the best thing I’d ever seen in my life.

One way to describe NeXT is Steve returning to the two things he missed @ Xerox.


I think the tradeoff with the Toolbox is that positioning controls with relative coordinates, and updating views when scrolling etc, is a huge PITA since you have to do it in application code – for example, I'm not aware of many classic Toolbox applications that had bottom window status bars before that required relative positioning. A few early applications just assumed 512x342 fullscreen (i.e. MacPaint.)

On the point of GrafPort still existing – Carbon was insanely backwards source compatible until QuickDraw was deprecated in the transition to 64-bit! [1] Conservatively-written 80s Toolbox code would work with some switching around of headers, and shimming getting/setting members of structs with functions.

[1] https://www.highcaffeinecontent.com/blog/20150124-MPW,-Carbo...


> for example, I'm not aware of many classic Toolbox applications that had bottom window status bar

I think that’s more either because they yet had to be invented or because giving up 16 or so pixels on a screen (the menu bar was 20 pixels high, IIRC) that’s only 342 pixels high wasn’t desirable.

> A few early applications just assumed 512x342 fullscreen (i.e. MacPaint.)

I think MacPaint can be forgiven for that. It was a miracle that it ran on a Mac with 128kB RAM.

An application on that machine had about 28kB free for a program. MacPaint allowed you to edit a 50kB bitmap, double-buffering the screen to avoid flicker, with full undo.

(And yes, paging to floppy disk isn’t fast. It did work, though)


Note the HANDLE count is kernel objects; windows and graphics objects will show as USER and GDI respectively. Each of these has its own heap and limits.


> 90s apps used these Windows handle controls and it was not a performance problem.

For a while there, at least on Windows 3.1 and before, possibly some Windows 9x versions -- you had a GDI heap and USER heap of 64k each (one 16-bit x86 segment). If you allocated too many HANDLEs, you could blow one of these heaps. So it still made sense to be judicious about how many windows you created. Most Web browsers and word processors, for instance, drew their documents in the client area and did not use subwindows to position text elements.


It wasn't usually a performance problem because before you hit that point you hit a more simple resource problem: up to and including Windows 95¹, GDI had significant 16-bit internals (at least partly, I assume, for compatibility with older apps), and there was a limit of 16,384 HWNDs and so that 16,384 active objects of any type that needed a HWND. This could be a noticeable limit if running a number of certain apps at once anyway, but some apps had a habit of "leaking" handles making it more common to run into.

IIRC this limit never applied to the NT family (NT, 2000, XP, …).

--

[1] I can't remember if this was resolved at all in the 98 releases, I imagine not


I remember running into this quite often. Apps would fail to draw completely and malfunction.


Do you know why they made those handles public instead of private to each app?


In the early days there was little need, nothing big enough to need that many would fit in the rest of the machine anyway.

Also they were global so apps could communicate - the message queue was based on sending things to window handles, and the more advanced IPC methods like DDE and so forth were built on that. It is also how anything that interested with the task list or interacted with the desktop (adding decorations to windows etc.) functioned. This doesn't work if local handles can conflict with those in the other app.

The amount of things that depended on HWNDs working this way is probably a significant part of why large chunks of GDI remained 16-bit in Windows95 despite things like the limit of 16,384 handles being an issue you could run into relatively easily by that point - too many existing apps & tools would have broken otherwise and limited people's desire to upgrade from 3.x.

So a combination of "no point introducing extra complexity, at least early on", "the global pool is actually useful", and "once it was done that way, it was very hard to refactor without breaking compatibility with much of the existing application base".

I think the compatibility layers on later versions did start separating the apps more, once breaking things was less of an issue (new versions existed that were directly compatible with newer APIs) so segregating the apps for stability reasons won out over being quite as backward compatible.


Windows can be interacted with cross process e.g. send an event to a window owned by another process, have a child window owned by another process etc.


> They were not used in apps with complex UIs because native controls were hard to skin

Every time I’m forced to use Windows I’m blow away by the clownishness of every application deciding to skin its own custom windowing controls.

This started happening some time around XP, I think?


It definitely started before: one of the reasons beta versions of Windows XP had a completely different theme was to prevent application developers from trying to implement the XP theme in some weird, unofficial framework and create broken and inconsistent looking applications by rendering the XP style themselves. As XP wasn't finished yet shipping every real iteration would've probably only caused more of these inconsistencies, so I think shipping the real theme close to release date was the right move.

If applications used the theme APIs, they'd run fine on both beta and production versions of Windows. If applications tried to render bitmaps over title bars and such, they'd look weirdly out of place, because the real theme was extremely different.

Unless you preferred the beta Windows XP style, of course, which some people did. I think there were a few hacks you could do to get the beta theme working on release versions of Windows.


> prevent application developers from trying to implement the XP theme in some weird, unofficial framework and create broken and inconsistent looking applications by rendering the XP style themselves

That certainly did not work, as billions of applications, including big ones, were using third party “XP-like” and “XP with some twist” skins both in Windows 9X and XP builds.

Microsoft very likely wanted to have some control over commercial skinning market (and make people making those broken things care about compatibility) — alternative themes were supposed to be available to users after being signed by Microsoft. However, you can count the number of those themes on one hand, because others' response was “providing a patched version of uxtheme.dll for each update”.

The other problem was that fashionable XP interface features like colourful side panels in Explorer and Control Panel were windowless controls made with internal layout engine, and neither was available to the public. So the only option was to re-implement those things more or less faithfully, which was done by many developers of commercial UI libraries.


That only happened after the official release, and of course Microsoft couldn't stop anyone from taking a screenshot of the title bar and buttons.

I'm not sure if they wanted to sell themes, really, all theming I've ever seen them sell was based on Windows Media Player and I don't think they did a lot of business in that. Most of the themes were free and the ones that cost money often came back for free a while down the line.

The explorer panels didn't seem to catch on outside of Windows Explorer. Most apps that implemented the bar also didn't seem to make good use of it, in my opinion. Microsoft Office had it, but it always made the screen feel a bit crowded in the way they stacked it with controls and panels, while being completely empty at other times. I think the panel made sense for explorer, but not much elsewhere.

I do wonder if there was an API for the side bar if you used the CLSID explorer interface.

I think Microsoft should've exposed the control, but at least they released a lot more native controls when Vista came around.


I meant that skinning has already been cool before XP, with various degrees of attention to detail and various amounts of system hacks. WindowBlinds for the whole system, application-level reskins. Even Java applets were once considered cool simply because they used their own UI toolkit! Moreover, Microsoft had essentially sold wallpapers and cursors as Plus packs.

However, after the release of XP developers did not stick to using correct native components that would automatically look like Windows 98 on Windows 98, and like Windows XP on Windows XP. They continued to reinvent everything via third-party skinning libraries, but now with kind-of-hip kind-of-XP styles. Random example:

http://web.archive.org/web/20041213230620/http://www.helium2...

Native menus don't work like that. The gradient between “Standard theme” and “Silver theme” background colors is someone's invention. Scrollbars should reach the top of the table views, and their native headers look different. Extra shadows here and there. etc., etc. Everything is improperly remade.

I suppose it was an important topic if they specifically introduced visual style signing at the time when system files and drivers were not even required to be signed. Maybe the perspective of new antitrust trials botched another EEE campaign, maybe the peasants just refused to bow to the king that time.

As for undocumented framework, look up "Windows DirectUser Engine" and "DirectUIHWND". Here's someone fighting with Raymond Chen in comments over IE pretending that having a copy of undocumented system library does not consist of using undocumented Windows APIs:

http://web.archive.org/web/20080329044328/http://blogs.msdn....

The name “DirectUI” is spilled in other comments:

http://bytepointer.com/resources/old_new_thing/20050211_035_...

Side note: as bytepointer archive is badly indexed for this or that reason, I've wasted more than an hour trying to find the post I vaguely remembered seeing. A single mention of "duser.dll" on HackerNews has finally helped me:

https://news.ycombinator.com/item?id=7811284

P.S. Nice contemporary controls re-implementing those Explorer panels from scratch (and copying the name):

https://www.codeproject.com/articles/3216/directui-window-as...


For the sake of completeness: find the differences between bytepointer.com link above, and this earlier copy:

http://web.archive.org/web/20061112210203/http://blogs.msdn....


Windows isn't any special compared to Linux or macOS though is it? IME 90's MacOS was most known for funny looking apps, the custom UI thing probably started with Kai's Power Tools:

https://www.google.com/search?q=Kai%27s+powertools+screensho...


That's not true; apps with non-native UI were usually scorned by Mac users. KPT and other Metatools or (whatever they called themselves that week) stuff was an exception.


I remember Borland shipping a toolkit with horrible built-in skins well before Windows XP.

I even vaguely recall MS jumping on this bandwagon with some MFC styles.


There was a fad for putting icons on dialog buttons. That was the most obvious Borland stylistic trait. Big green check mark on "OK" etc.

That, and Delphi applications not having a minimize to tray animation due to the application window technically being invisible.


Hang on hang on...

> There was a fad for putting icons on dialog buttons. That was the most obvious Borland stylistic trait. Big green check mark on "OK" etc.

This I remember well. It was a hallmark.

> That, and Delphi applications not having a minimize to tray animation due to the application window technically being invisible.

Say what now?!


The VCL has a window managed by TApplication and it's the window which shows up in the task bar, but it's not the application's main window, which is generally a TForm descendant. When you minimize the main window (certainly on Windows 7 and before - I'm not sure about what happens these days) it would just vanish, while a tiny little animation not related to the main window would briefly show disappearing into the task bar button.

The application's window message queue was used for things like coordinating background thread actions with the UI thread and other general purpose stuff - I don't remember the details and it's been a long time since I read the VCL source.


Wow. I had no idea. Thanks!


It's curious that in Qt Widgets QWidgets (that are generally "alien windows") aren't cheap either. If you implement a list view from scratch, you shouldn't create the list items as QWidgets otherwise your application will become slow very quickly.

What you want to do instead is to use custom drawing and event handling code for those list items. The it will be very snappy.


You can take advantage of QListView to handle high item count lists and it'll just request the data it needs when it needs it, scales to millions of rows without issue, you really don't want to draw it yourself.


The Start button is (or at least used to be) a Window. And in the first Release of they forgot to remove the window control menu - the thing that opens/used to open when you click the program icon on the top left corner. Obviously there was no program icon to click, but you could use a shortcut to open it. Then you could select "move" and move the start button on the task bar or even close it. After you closed it, it was gone and you had to kill explorer.exe via task manager and restart it, to get it back. I can't remember the shortcut, it must have been something like alt+-.

In older programs this menu is still around and you can still use it to close programs, like you did in Windows 3.1 days. Even doubleclicking the icon in the top left corner still works to close those programs.


> I can't remember the shortcut, it must have been something like alt+-.

It's alt+SPACE. Very handy if you manage to get a window off screen, you that menu almost always shows up on screen, and you can select Move (possibly by hitting m), and then move (or drag) your mouse and the window comes back.


> It's alt+SPACE.

Maybe, but I just tried it and it seems to open some type of search.

> Very handy if you manage to get a window off screen, you that menu almost always shows up on screen, and you can select Move (possibly by hitting m), and then move (or drag) your mouse and the window comes back.

I used to use it exactly for this, but it seems like they fixed something in the past 10 years, because that does no longer happen for me. I think the last time it happened was in the Windows 7 days. That's probably also why I forgot the shortcut.

I still use the double click in the top left corner to close windows, but they kill that for more and more programs. For some time it still worked for some programs with reduced chrome, like tabbed browsers, when I clicked on a few of the blank pixels in the top left corner.


> > It's alt+SPACE.

> Maybe, but I just tried it and it seems to open some type of search.

That's because you installed PowerToys, and the PowerToys Run module takes over the Alt+Space key combo.

This really pissed me off the first time I wanted to use Alt+Space to rescue an offscreen window and I had no idea what this search box was.

It's a real problem with the kids who maintain Windows today and the "modern" Windows apps. They just don't know, and don't care, what the classical keyboard shortcuts are and how important they can be.

Here is one example of a GitHub issue that was closed as "wontfix":

https://github.com/microsoft/PowerToys/issues/13860

You can fix this by changing the "activation shortcut" for Run in the PowerToys Settings, or by disabling PowerToys Run entirely.

I changed it to Win+Alt+Space and now Alt+Space works like it always has.

Also, 'toast0' left out an important step in their description. You need to press Alt+Space, then M, and then any cursor key, and finally you can use the mouse to move the window.


> It's a real problem with the kids who maintain Windows today and the "modern" Windows apps. They just don't know, and don't care, what the classical keyboard shortcuts are and how important they can be.

These days (since Windows Vista, hah) the easiest way to rescue an offscreen window is Win+Arrow (the "Aero Snap" keys). (It's also the easiest way to do most of the other old control menu things: Win+Up is Maximize/Restore and Win+Down is Minimize/Restore. The two lacking things are Move when you actually intend to keyboard move and Size for keyboard resizing, though both are less usual at modern resolutions than they used to be.)

If someone has installed PowerToys the likelihood they are using FancyZones increases and so too the likelihood they already use Win+Arrow shortcuts heavily (especially if they let FancyZones take over them for zones).

> Also, 'toast0' left out an important step in their description. You need to press Alt+Space, then M, and then any cursor key, and finally you can use the mouse to move the window.

You need to push a cursor key because Move was originally intended as an accessibility feature when you couldn't Move a window with the mouse (or needed more precision than your mouse supported) and needed to use the keyboard arrows. Also why Size exists in that old menu. If you want to talk about knowing the history of classical keyboard shortcuts, the use of that menu for keyboard accessibility to things instead of the mouse is an important part of why that menu existed in the first place (and part of why it feels so vestigial today because mice have improved so much since the early days of Windows and screen resolutions have grown so much since the early days of Windows that trying to precisely to-the-pixel move or resize windows with the keyboard today seems silly).


> You need to push a cursor key because Move was originally intended as an accessibility feature when you couldn't Move a window with the mouse (or needed more precision than your mouse supported) and needed to use the keyboard arrows.

I would say less accessibility, and more the mouse was optional with Windows before 95, so all features needed to be keyboard friendly. I think they became 'required' by spec in 95, but you could still do everything with a keyboard. Mousekeys was included in Win95 and is more of an accessibility feature.


Yep, and Mousekeys still exists into Windows 11. It's a useful accessibility feature.


> trying to precisely to-the-pixel move or resize windows with the keyboard today seems silly

I've recently discovered that GNOME switches between fast and precise keyboard dragging with Ctrl, and snaps to window edges on Shift. See process_keyboard_move_grab():

https://gitlab.gnome.org/GNOME/mutter/-/blob/main/src/compos...


Try Shift+Esc, maybe that works.


I don't think Shift+Esc does anything on Windows. In Firefox it opens a "Process manager" but that's just inside the browser, nothing related to Windows.


The start button is still a window, but it's not a top-level window. It's a child window of the taskbar. And has been so since Windows 95.


Not anymore. On Windows 11 you can use spy++ to check the taskbar window and it will show up a single window and everything inside it, start button or program buttons, all are not a window. This seems to be the case for any app that is using <whatever is the new windows app framework>.


As far as I remember, Alt+- opens the menu of an MDI child window. For the current window (which is generally more useful, MDI applications being very rare these days), it's Alt+Space as mentioned by several people.


I still use the window menu shortcut Alt+space and then C to close the window, it is more easy to press compare to Alt+f4 (such a non-ergonomic key combination, compare to macOS cmd+w)


Ctrl+Q works in most (though yes, certainly not consistently all) Windows applications. Cmd+Q is also what you'd use on macOS to quit an entire application (Cmd+W is close single window), so the cross-platform ergonomics/muscle memory are actually somewhat preserved. Most Windows applications that still use MDI for some reason or that have tabbed browsing interfaces (appropriately) generally use Ctrl+W for window or tab closing, respectively.


Anything in Windows that could get keyboard focus basically had to be a window. If you could tab to it, window.


Windows (unlike X) had built-in windows classes (for example: buttons, checkboxes, input fields) that you could use to turn a window into a standard control. That's why idea "everything is a window" worked well in Windows.


I remember when Qt introduced the "alien windows" concept, in 2007: https://web.archive.org/web/20080205085059/http://labs.troll...

As they say, they had to do it to eliminate flicker.

Which goes to show that if your elegant design can't scale, it will be corrupted until it can. Something something "worse is better"


i assume by 'windows' you mean 'microsoft windows', because otherwise your comment makes no sense

smalltalk has worked this way since at least 01976, but the word they used instead of 'window' was 'view'. see for example steve burbeck's 01992 'how to use model-view-controller' which is describing smalltalk-80 https://www.researchgate.net/publication/238719652_Applicati...

> Views are designed to be nested. Most windows in fact involve at least two views, one nested inside the other. The outermost view, known as the topView is an instance of StandardSystemView or one of its subClasses. The StandardSystemView manages the familiar label tab of its window. Its associated controller, which is an instance of StandardSystemController, manages the familiar moving, framing, collapsing, and closing operations available for top level windows. Inside a topView are one or more subViews and their associated controllers which manage the control options available in those views. The familiar workspace for example has a StandardSystemView as a topView, and a StringHolderView as its single subView. A subView may, in turn, have additional subViews although this is not required in most applications.

so it's not a peculiarity of x-windows; it's how windows/icon/menu/pointer guis have been built since the beginning. (i'd say 'it's how guis have been built since the beginning' but of course sketchpad, grail, nls/augment, and genesys didn't work this way, and they were certainly graphical user interfaces, even if very different in style.)


> i assume by 'windows' you mean 'microsoft windows'

Yes of course he did, and you don't have to guess, because the phrase "Windows for example uses" makes Windows a singular noun, compare with "windows for example use". There is no possible ambiguity in the post you replied to.


Wait are you talking about Microsoft Windows? Your post makes no sense, I can't make heads or tails of it :(


sam, knock it off

find a hobby other than harassing me on hn

if you can't control yourself, take a break from hn

(most recent previous incident, though not the only one: https://news.ycombinator.com/item?id=39402249)


[flagged]


I read it as an octal year at first and was confused on multiple levels.


GTK also uses windows for input-related widgets. It’s simply convenient to have a separate window context. Although these windows are GDK windows, which may or may not have system windows underneath, afair.


> Windows doesn't have the same client/server overhead as X though.

Yes it does. You think they run that in the same address space? When there are multiple processes with different privilege levels running their UIs? Maybe this comment was accurate for Win3.1, but for a long time there is absolutely a client server architecture behind it.

Anyway one of my favorite uses of HWND is to use a non visible window as a worker thread mechanism. Each HWND is tied to a message pump in the thread that owns it. So you can send it messages, and boom, you have a thread API...


On all "Classic" Windows and on NT from NT4 until DWM in Vista, GDI was not client-server instead it would draw directly to VRAM With some kernel assistance on NT (before NT4, GDI calls were handled by separate server process).

This is why misbehaving application could get you the famous "trailing window" effect where moving a window would leave partly painted trace of it behind - you had to wait for some other coffee to properly repaint that other area.

With DWM, your GDI windows are backed by memory that at most will be a texture in DirectX, which will be then composited by DWM (equivalent of X11 extensions to capture window drawing into pixmap instead of lowest common denominator implementation of DIX/DDX that would draw immediately to framebuffer)


Yup... I was working on a password manager application for Windows a few years ago, which was easy for most applications using the native UI because of all controls having window handles - and was then disappointed that it didn't work in cross platform apps such as Firefox.


Yeah it was already the way of doing GUIs in 16 bit days.


>Windows doesn't have the same client/server o̶v̶e̶r̶h̶e̶a̶d̶ ̶a̶s̶ ̶X̶ ̶t̶h̶o̶u̶g̶h̶

...features and functionality as X, regretably


Another awesome aspect of X11: Xembed. Since it's "windows all the way down" you can have apps (rather than the window manager or root window) be the parent of other app windows.

Two nifty examples of this:

* https://tools.suckless.org/tabbed/

* https://surf.suckless.org/


Win32 does allow you to change a top-level window into a child window of another process. You just get terrible performance if you actually attempt to do this.

For a more practical way to simulate a top-level window being a child window of another program, you make the top-level window Borderless, and perform all the necessary window management to maintain position, dimensions, and Z-order.


Why do you get terrible performance? I vaguely recall reading that doing this ties the input queues together, so that all (input?) messages get dispatched to both processes, which then both need to have their message loops respond in a timely fashion. Is that it?

Anyway, I believe the Microsoft Management Console (MMC) actually does this. The content windows (at least in some cases) belong to a different process than the surrounding UI.

Also, WebView2 (the new Chromium-based Edge webview) runs out-of-process, but maybe it does some things in the embedding process to improve performance?


Microsoft Management Console loads DLLs into the process, it does not use a separate process for the snap-in. (Just checked this in a debugger)

As for why there would be bad performance for putting a window into another process's window, I can only speculate. It takes something like 10000+ CPU cycles for Windows to finish switching to a different thread or process. If this is happening for every message that is handled by both the parent and the child window, that would be a lot of overhead.

I haven't checked if the Out-of-process webview is the EXE that owns the window or not.


Hmm, maybe the MMC child windows were owned by a different thread (which would also involve a separate message loop and a context switch) but not a different process? I distinctly remember finding some windows in there that were not owned by the main thread, but I don't have my notes accessible at the moment.


AFAIK this is how audio plugins are embedding themselves in DAWs on Linux.

No idea how that's gonna work on Wayland.


For it's time the way X did things was incredibly elegant and it worked really well and did things that seemed very sophisticated long before other systems could handle remote desktops.

There's a lot of stuff that seems hackish about modern stuff, but the needs are different. (Perhaps it seems worse to me when the modern stuff is grafted on top of X)

The thing that I remember being horrific about X was the abuse of pointers in some of the toolkits like Motif.

When GTK came along it seemed a lot easier to write to. As did Tk.


XView (https://en.wikipedia.org/wiki/XView) was a really great way to write GUI applications from C programs. It extensively (ab-)used varargs:

  frame = (Frame)xv_create (NULL, FRAME,
                            FRAME_LABEL, argv[0],
                            XV_WIDTH, 200,
                            XV_HEIGHT, 100,
                            NULL);
  panel = (Panel)xv_create (frame, PANEL, NULL);
  (void) xv_create (panel, PANEL_BUTTON,
                    PANEL_LABEL_STRING, "Quit",
                    PANEL_NOTIFY_PROC, quit,
                    NULL);
  xv_main_loop (frame);


> ou can still find this many-window style is in some old fashioned X window managers, such as fvwm. When fvwm puts a frame around a window (such as the ones visible on windows on my desktop), the specific elements of the frame (the title bar, any buttons in the title bar, the side and corner drag-to-resize areas, and so on) are all separate X sub-windows.

This isn't even really that old-fashioned. Any X11 WM that draws server-side-decorations is going to do this to some extent. I didn't realize fwvm uses so many windows for its decorations, but at the very least, a WM is often going to reparent the window created by the client as a child of a WM-created window, where the titlebar and drag-handle-borders will be drawn.

I imagine GNOME/X11 generally doesn't do this anymore, due to their bizarre obsession with client-side decorations. But any (IMO) sane WM that agrees with me that it's a good user experience to make all windows look visually similar, will do something like this.


> But any (IMO) sane WM that agrees with me that it's a good user experience to make all windows look visually similar, will do something like this.

Have you looked at Discord on Linux? It ~~not using~~ trying not to use CSD just looks fucking terrible and has been one of my main grips with it... If an app isn't designed around having SSDs (or is something like a game) it just looks majorly out of place.


It's how Windows does it. My memory is getting hazy, but I'm pretty sure it's how macOS Classic did too back in the day.

OP is one of today's lucky 10,000 I guess.


An interesting part of the X protocol is XGrabPointer (and XGrabKeyboard). These force events to be delivered relative to a particular window instead of to the focus window. Cascading menus can be implemented by making a stack of such grabs: push when you open a submenu, pop when you ESC back to parent.

Anyway, so it's very useful that everything in X is a window, because it works well with this input grabbing. Also it's nice for borders: the border was one outer window, and the drawing area was a smaller inner window.

I don't quite remember anymore, but I think a bad part about using the X's windows is that the coordinates were limited. Sure you only need 12-bits or so for screen coordinates, but it's convenient if you had 64-bits to handle any possible clipping or relative offset situation.


I don't think that's unique to X windows, though - pretty much all GUI platforms have a similar concept, otherwise any time you accidentally drag your mouse outside of a window you'd start sending events to another application.

On MS Windows it's called "Capture".


> otherwise any time you accidentally drag your mouse outside of a window you'd start sending events to another application.

macOS does precisely that. Open a Chrome window and put a Finder window over it, then move your mouse and do a scroll gesture - the target will always be whatever is below the mouse cursor at that moment, even if you don't actively select the window.


It makes sense for mouse scrolling to target whatever the mouse is pointing at, just like all the other mouse buttons. Keyboard scrolling needs to use the current input focus to select a target because you can't point with the keyboard.


Well I think this is desired behavior. But what if you grab a slider (so that the mouse button is held down), and drift out of the window? I thought some versions of Windows didn't handle this well, the slider would jump back home or something unless you kept pointing at it. The way it should work: as long as you are holding the button down, it should not matter what the x-coordinate of the mouse is if it's a y-slider, and vice-versa.


That's also the behavior on Windows


It's also the behavior on Linux with X11 (haven't tried Wayland)


At least on XFCE with X11, this behavior is configurable, you can enable it or disable it, as you wish.


Note that this is a feature that was added in Windows 10. Previous versions of Windows didn't have this functionality (you had to click on a window to scroll in it).


An X-Mouse mode was available since at least Win98SE [1]. It was hidden and you had to enable it in the Registry [2], typically via Tweak UI.

That mode would move the input focus without actually clicking on another window. You could see the caption bars change color accordingly, but the "temporarily" focused window could be set to either stay in it's original z-order or moved to the top.

Windows 10 uses a different method: it doesn't change the focus and only sends mouse scrolling events to the target window. That's less powerful, but probably more intuitive for us non-*nix users.

[1]: https://stackoverflow.com/questions/70599589/how-do-i-turn-o...

[2]: https://superuser.com/a/19643


But it wasn't for a long time. I think it was broken until at least windows 7.


This is also why you can't change the volume or start a screensaver while a drop down is open.


Confusingly, in classic X Window terminology, the "server" is the display manager running on the user's workstation, and the "client" is the application running on a remote machine that wants to display something. This article uses that terminology.


It's OK terminology. In networking, clients usually initiate the connection to a server, a server is usually intended to be able to serve multiple clients, and servers tend not to talk much with other servers that might exist on a network.

And that's how it be with the X Window System.


Well, and obviously X is providing a windowing and drawing service to the clients. Doesn't matter who initiates the connection or the M:Nness of the communication, X is providing the service to the applications, and they are not performing any service for X.


Yup.

Compare: Windows Services for Linux.


An X Server is a server in exactly the same way and for the same reason that a web server is a server (or a database server, or a file server, or a DNS server...). It runs in perpetuity and waits for connections from ephemeral clients who will direct it to do stuff. I genuinely don't know anyone who remained confused about this once this was explained to them the first time.


One slight variation on that way of thinking about it - a server mediates access to a resource for its clients.

A file server mediates access to a file system; clients connect to access files. A database server mediates access to a collection of data; clients connect to access data. A print server mediates access to a printer; clients connect to access the printer.

And an X server mediates access to the graphics device; clients connect to access the display and its related peripherals (keyboard, mouse).


I think a key part of why this was confusing to many back in the day was that the big thing at the time was "client-server computing".

If you wanted to do email on your home computer, you'd [buy and] install an email client.

You wanted to go on AOL? Install the AOL client.

Need to use Lotus Notes? Have MIS send a guy over to install the Notes client.

Wanted to run X programs? Install an X server. What? Seemed weird!

You still hear that terminology some, but nowadays you're much more likely to hear about an email app.


> I think a key part of why this was confusing to many back in the day was that the big thing at the time was "client-server computing".

Anecdata, but that's why it's confusing to me even today.


Yep. Networking was the beginning of the end of anything comprehensible.


I still don’t know the difference between “upstream” and “downstream!”

Envoy uses the opposite definitions from what I’m used to. And has a perfectly cromulent explanation for why; I’m convinced. But now I don’t know why I started calling them the opposite.


> I still don’t know the difference between “upstream” and “downstream!”

I just envision being Darkly Noon, sitting at the river bed, watching the giant shoe floating into view from upstream, going downstream.

Anything else don't make sense.


Data goes in both directions. Is “upstream” where the requests come from, or where the responses come from?


From your example, one could envision an extended edition where, shortly after the shoe goes out of view[1] floating past him, someone shouts "anyone missing a shoe?"

That response would then come from downstream from Darkly.

My point was that it's a matter of perspective. And it requires a certain well-defined gradient (the river), I don't think "upstream" and "downstream" make much sense when all you have is a lake.

[1]: https://youtu.be/eBCDXN6HBS4?t=164


Good point. I also think it's confusing because it's from the point of view of the program instead of the user. I.e., the program is sending draw commands to some server to get rendered.

But as a user, the IO devices that I interact with (keyboard, mouse, display) are the client that connect to some backend (whether a web server or a remote program).


Funnily enough, both macOS (and nextstep and iOS, though differently combined) have a "windowserver" that applications are clients of, similarly BeOS, and even Windows NT pre NT4 and since DWM.

It's the MacOS Classic and GDI and similar direct-to-hw toolkits that are now outliers


Consider a print server. clients connect to it, pictures come out. a display server is the same. clients connect to it to print pictures and get user input.


It's the reverse that would be confusing. Your "web client" would have to be called an "X server"!

I suspect the X terminology is confusing to two groups of people:

1. Those who are used to the idea that when the computer and the display are separated by distance, the local display is a mirror of the remote machine's desktop, courtesy of a service on that machine to which the local display connects as a client. X isn't a remote desktop mirroring protocol, though; those people have the wrong model.

2. Those who are used to the idea that a server is something that runs in the background (daemon), not visible in the desktop. How can the X desktop be the server, when it's shoving pixels in your face, right in the foreground? Well, you know, someone serving you a punch also does it in your face.


Honestly, this isn't that confusing. I think even back in the day, it didn't take long to understand the reasoning behind this naming.


Because that is the correct terminology in this context.


I was surprised the first time I wrote a GUI framework in C, and i happened to be like this as well, everything on the screen just happens to have the properties which a window has.. A position, bounds, a drawing call, some child elements. So it emerges naturally that everything is, at the very least, a window.

So yea, I'd argue this is not some strange quirk of the X-Window system, but rather a natural property which the wise hackers decided not to spend extra effort on trying to tame.


I never thought of this as a peculiarity of the X Window System (though the client-server aspect of it was a lot of what made X, X), but I keep forgetting that this is not something modern developers know about.


I mean if we disregard the name, this is a very common architecture. Everything is a DOM node etc.


'Programming X is like reading one of those French philosophers where afterwards you start wondering whether you really know anything for sure.' [1]

[1] Thomas Thurman - https://www.youtube.com/watch?v=GWQh_DmDLKQ https://people.freedesktop.org/~daniels/lca2013-wayland-x11....




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: