3 Win32 Backend
dxtr edited this page 2026-10-18 16:01:10 +02:00

Win32 Backend

The system cl-windowing/win32 is the backend for Windows, on user32 through cl-win32. It registers itself as :win32 and needs Windows 10 version 1607 or later.

(asdf:load-system :cl-windowing/win32)

(win:with-window-system (window-system)          ; :backend :win32, Windows' backend
  (win:with-window (window window-system :title "Hello" :width 800 :height 600)
    ...))

open-window-system takes no options for it. On Windows it is the backend open-window-system uses without :backend.

Windows

  • Windows have the system's title bars and borders: window-decorations is :server-side.
  • A new window gets the keyboard at once, so its first events are a :resize and a :focus-in.
  • app-id is not used: Windows groups the windows of a process itself.
  • set-window-size sizes a window's client area, unless the window is maximised, minimised or fullscreen, when it returns nil.
  • A fullscreen window is a window without a frame covering its display: the display's mode is not changed, and the desktop goes on running around it. It becomes fullscreen at once, and leaving fullscreen puts it back where it was, maximised if it was.

Scale and size

A window's scale is the DPI of the display it is on over 96: 3/2 at 150%. Windows sizes windows in pixels, so a window's size in its coordinates is its pixel size over its scale, rounded. At a fractional scale, window-pixel-size can then differ from the window's real pixel size by a pixel, which the swapchain, sized by Windows to the client area, makes up. A window moved to a display of another scale keeps its size in its coordinates.

Input

  • Keys are named by their scancodes, which the backend maps to the Linux kernel's key codes, so event-key names the same physical keys as on Wayland; the layout's virtual keys give event-symbol.
  • Text comes as Windows translates key presses, dead keys included.
  • AltGr is not reported as Control and Alt, though Windows sends it as both: it types characters, and they arrive as :text.
  • While a button is held, the window keeps the pointer's events, even when the pointer leaves it. A window that loses the pointer meanwhile, as to Alt+Tab or to a modal dialog that disables it, gets the button's release at once, at the pointer's last place, since Windows sends none.
  • Input methods speak IMM32. A window's input method is off while it takes no text input, so keys reach it as they are typed. Windows' input methods are not told the text around the caret, so they never ask to delete some, and they do not compose in popups.
  • Cursors are the user's system cursors; where Windows has none for a cursor, the nearest it has, such as the arrow for :zoom-in.
  • A window confines the pointer, or captures it, by keeping it within its client area, or at one point of it, while it has the focus and the pointer has come over it. A captured pointer's motion is the mouse's raw input, in its own counts.
  • The clipboard holds Windows' Unicode text. While the session is locked, Windows gives no program the clipboard, and clipboard-text signals window-system-error.

window-system-capabilities always includes :server-side-decorations, :fractional-scale, :keyboard and :clipboard, and :pointer and :pointer-capture where a mouse is present.

Popups

Popups are windows without frames owned by their parents' windows, never activated. The backend places them as place-popup says, within the work area of the display their rectangle is on, and places them again as their parent moves. A popup that grabs gets the keys while the program has the focus, and is dismissed when the focus goes elsewhere, as to another program, or when the user presses a button on a window's title bar or border, as Wayland's compositors dismiss one on a click outside the program's windows.

Dialogs

A dialog is a window owned by its parent's window, so it stays above it, is minimised with it, and has no button on the taskbar. It opens over the middle of its parent, within the work area of the display its parent is on, or where Windows chooses if its parent is minimised. A modal dialog disables its parent's window while it is open, with EnableWindow, as Windows' dialog boxes do: Windows gives the parent no input, and shows the dialog when the user clicks the parent. The parent is enabled again just before the last modal dialog on it is destroyed, so that Windows activates the parent in its place. See Dialogs.

Its thread

A Win32 window delivers its messages only to the thread that created it. So each window system runs a thread of its own, named "cl-windowing win32", which creates every window and handles their messages. create-window and destroy-window, from whatever thread, are handed to it, and process-events waits for its events, so the thread rules are the core's on Windows too.

While the user drags a window's border or title bar, Windows runs a loop of its own in that thread, and events keep coming meanwhile.

Vulkan

cl-windowing/vulkan creates surfaces for its windows with VK_KHR_win32_surface; vulkan-instance-extensions names it. See Vulkan Surfaces.