- C++ 95.6%
- CMake 4.4%
| libbase@639dd11b4a | ||
| liblog@151d5d12a4 | ||
| src | ||
| utestpp@7715694674 | ||
| .gitmodules | ||
| CMakeLists.txt | ||
| README.md | ||
WM
Requirements/Features
- fully compliant with https://www.freedesktop.org/wiki/Specifications/wm-spec/ and ICCCM
- multi display capable
- support for various workspaces (unlimited)
Workspace
A workspace is a unique window arrangement for a sub set of all displays, ie. the workspace is bound to some of the available displays. If a workspace is shown all other workspaces that share the same displays are hidden.
It is possible to have some monitors with one workspace while the remaining show a different workspace. The number of parallel workspaces should be limited only by the number of available displays.
Quiet Workspaces
A workspace can be marked as quiet, meaning that no notifications will be presented to it.
If multiple workspaces are shown, having one quiet workspace will disable notifications for all other workspaces as well.
Workspace Naming
Workspaces can be named easily. The name can be used to operate with this workspace.
Workspace Operations
Close
Close all windows associated with that workspace and delete the workspace from internal structures.
Rename
Change the name of the workspace. There is a default name for new workspaces.
Save
Save the layout of this workspace with its applications.
Restore
Restore a workspace together with its applications and layout.
Fast Movement
Movement between workspaces and windows should be possible very fast, usually using a few keystrokes.
Design
Software
Screens & Windows
- The wm connects to N physical screens. Each of the screens can display any number of windows. Windows can be moved between the screens.
- If a screen is lost (eg. it is turned off or disconnected), the windows that were displayed on that screen are moved to one or more of the remaining screens.
- If a window becomes visible, it is displayed on one of the screens. If the window was visible before, it is displayed on the same screen as before unless that screen was turned off in the meantime.
Virtual Screens
- Each physical screen displays one of multiple virtual screens. A virtual screen is also called a window group. A window can be part of one window group at a time (it would be nice to allow a window being part of multiple groups at the same time, though this would complicate things for now -- let's leave it for the next version).
- A window group stores a layout for its windows.
Common Pitfalls
User Input
Reading input from the user usually requires opening an input window and waiting for the user to finish the input by pressing the return key. If we want to use our internal window handling to present, align and decorate the input window we need to decouple the waiting for the result from the window management.
Layout
- everything that is related to X should be hidden in a separate module
- user interface is handled completely in its own thread
- X connectivity is handled in a separate thread, as window management makes use of X functions to move and resize windows, the window management takes place in the same thread. This adds a non-blocking requirement to window management functions.
- The main loop of the application reads X events and forwards them to event handlers.
- while waiting for user, key commands are ignored
Decisions
wn::x depends on wm::mgmt
Having wm::x using wm::mgmt allows better switching of the underlying
user interface environment.
Interfaces to support the decision:
-
mgmt::windowis an abstract class that provides window control functions and must be implemented by the underlying library. This needs to be done anyways. Alsomgmt::screen. -
x::modulemust translate events internally and call the appropiate functions, that would lead to a more powerful interface formgmt::module(add_window,del_window,key_pressed,create_screen,remove_screen,resize_screen) These functions need to be implemented as well if we choose the other way round, however, we have the interface for the wm close together.
Say wm::mgmt depends on wm::x. wm::x would then have to export an interface
to add listeners to it, as well as implementations usual to UI systems (e.g.
moving a window or getting the size of the screen). When adding support for a
different window subsystem, all these interface need to be abstracted and than
implemented for the target system.