KWin/Hacking

From KDE Community Wiki

Communication

Mailing list

The KWin mailing list is [email protected]. It's rather low traffic.

IRC

The KWin development IRC channel is #kwin on Libera Chat. General KDE development is in channel #kde-devel, user support in #kde

Bugzilla

The bugs.kde.org product for KWin is 'kwin'. Information about the various components and the priority system is documented on KWin/Bugzilla.

KWin parts

KWin consists of several parts:

  • The KWin core, located in toplevel directory, which implements the window manager and compositor.
  • The decoration plugins, located in clients and kdeartwork/kwin-styles, which are responsible for the visual representation of the windows.
  • The effects plugins, located in effects/*, which are responsible for compositing effects
  • The libkdecorations library, located in libkdecorations/*, which is used for communication between the core and the decoration, and also implements some shared functionality for the decorations.
  • The libkwineffects library, located in libkwineffects/*, which is used for communication between the core and the effects and also implements some shared functionality for the effects and the compositor.
  • KControl modules, located in kcmkwin/*.
  • The KWin Scripting bindings for JavaScript and QtQuick are located in scripting/*
  • KWin Scripts in JavaScript and/or QtQuick are located in scripts/*
  • The Window and Desktop Switching framework is located in tabbox/*

KWin structure

KWin has relatively few classes. The two main classes are Client, which represents windows on the screen, and Workspace, which represents the whole screen and manages windows. Since KWin also needs to track unmanaged windows for compositing, there is a base class Toplevel for all windows, from which Client inherits, and from which also class Unmanaged inherits. A third inheriting class Deleted keeps a copy of the window pixmap for animation when a window is closed. These classes are rather large, because they fulfill complicated tasks. In order to reduce the size of their source files these some functionality is in a separate .cpp file grouped by their purpose. Lately, the functionality is getting split out of Workspace.

Window Manager

The following lists the source files relevant for the core of the window manager:

  • workspace.* - core of class Workspace
  • client.* - core of class Client
  • toplevel.* - core of the base class Toplevel
  • unmanaged.* - core of the class Unmanaged
  • activities.* - Functionality related to Activities
  • appmenu.* - Functionality for embedding the Application's menu into the window decoration
  • activation.cpp - focus handling and window activation
  • client_machine.* - detects whether a Client is on a local or on a remote system
  • cursor.* - Mouse cursor related functionality like mouse polling
  • deleted.* - core of class Deleted
  • dbusinterface.* - Implementation of KWin's DBus interface, delegating to other classes
  • events.cpp - event handling is in events.cpp
  • focuschain.* - The Focus Chain for each desktop and most recently used Clients
  • geometry.cpp - geometry-related code
  • layers.cpp - stacking-related code
  • manage.cpp - code dealing with new windows
  • netinfo.* - Implementation of KWin's sub calles for NETRootInfo and NETWinInfo
  • outline.* - code for showing an outline when e.g. using Alt+Tab or quicktiling
  • placement.cpp - window placements algorithms
  • rules.cpp - code for window-specific settings
  • screenedge.* - code for screen edge activation
  • screens.* - multi-screen handling code
  • sm.cpp - session management code
  • tabgroup.* - Window tabs related code
  • thumbnailitem.* - QML DeclarativeItem to render a Window Thumbnail (or Icon without Compositing)
  • useractions.* - handling of the Alt+F3 menu, shortcuts and other user actions
  • virtualdesktops.* - Functionality related to Virtual Desktops

Compositor

The following lists the source files relevant to the compositor:

  • composite.* - code related to redirecting windows to pixmaps and tracking their damage
  • effects.* - support for compositing effects
  • eglonxbackend.* - OpenGL backend using EGL for either OpenGL or OpenGL ES
  • egl_wayland_backend.* - OpenGL backend using EGL to render to a Wayland surface
  • glxbackend.* - OpenGL backend using GLX
  • lanczosfilter.* - Lanczos Filter for improved OpenGL based thumbnail rendering
  • overlaywindow.* - the Overlay Window used for Compositing
  • paintredierctor.* - Redirects painting of decoration widget into a paint device for usage by the Scenes
  • scene.* - base class for compositing backends, with shared functionality
  • scene_basic.* - a very simple testing compositing code
  • scene_opengl.* - compositing backed using OpenGL
  • scene_opengl_egl.cpp - egl specific part of OpenGL compositing backend
  • scene_opengl_glx.cpp - glx specific part of OpenGL compositing backend
  • scene_xrender.* - compositing backend using XRender
  • shadow.* - Window Shadows

The implementation of a custom scene can be found in KWin/Hacking/Scene.

Helper Classes

The rest of the files contain additional helper classes:

  • atoms.* - so-called atoms (symbolic names for constants in X)
  • bridge.* - communication with the decoration plugin
  • geometrytip.* - window displaying window geometry while moving/resizing
  • group.* - grouping related windows together (warning! This is currently really messy and scary code that should be rewritten).
  • killwindow.* - handling of the Ctrl+Esc feature
  • kwinbindings.cpp - KWin's keyboard shortcuts (used by kdebase/kcontrol/keys)
  • notifications.* - for KNotify
  • options.* - all configuration options for KWin are stored in this class
  • decorations.* - loading of the right decoration plugin
  • utils.* - various small utility functions/classes
  • xcbutils.* - wrapper classes for accessing XCB

KWin also uses code from kdelibs, specifically files netwm.cpp, netwm.h, netwm_def.h and netwm_p.h from kdelibs/kdecore. These files implement support for the EWMH window manager specification, originally called NETWM (hence the filenames).

KWin Decorations

If you want to develop a decoration plugin for KWin, you can use follow this HOWTO. The HOWTO does not include the latest changes in KDE 4. These plugins have to be written in C++.

If you prefer designing a theme, you can use Aurorae (shipped with KWin), deKorator or Smaragd. For Aurorae there is a tutorial on techbase and it is recommended to use AuroraeDesigner.

It is also possible to develop window decorations using QML. But the API is still considered unstable and because of that not yet documented. An example is the Plastik decoration since 4.10.

Developing KWin

Building KWin

Please see KWin/Building for Qt4 and KWin/Frameworks for Qt5

Restarting KWin

Since KWin takes care of focus handling, first killing KWin and then launching a new instance can cause focus trouble. Therefore it's possible to run 'kwin --replace', which will start a new KWin instance and tell the old one to quit.

Handling the case when KWin crashes

Again, without KWin running there may be focus problems. To restart KWin when not being able to focus KRunner or a Konsole switch to a text console, and run 'DISPLAY=:0 kwin --replace' (and then you can run 'kwin --replace' again from X).

If KWin is temporarily unusable because of some change and e.g. crashes during startup, it is possible to run another window manager, for example Metacity, Compiz, OpenBox or FVWM (the command is similar to restarting KWin, i.e. 'metacity --replace', 'compiz --replace', 'openbox --replace' or 'fvwm -replace'). A good idea is also to have the distribution's KWin around to be able to switch to this if the development version is broken.

Debugging KWin

Focus problems once more. It is not possible to debug KWin in gdb in the X session that KWin is managing, because that'd block focus and window operations. It is necessary to switch to a text console and attach to the running KWin instance from there, or launch it as 'DISPLAY=:0 gdb kwin'.

Since KWin is such an important component of KDE, it is usually better to start another X for development.

Starting separate X for testing KWin: use a separate user, login to a text console and run "( X vt10 :1 -terminate &); sleep 5; DISPLAY=:1 xterm". This launches another X with DISPLAY=:1 on virtual console 10 (Ctrl+Alt+F10) with xterm. Then it's normally possible to run just KWin or whole KDE with startkde (in which case it's a good idea to disable xterm from session management in KControl->KDE components->Session manager).

Another solution is to use Xephyr which allows having the KWin which is getting debugged on the same screen as the IDE. But some features are not available on Xephyr like OpenGL-based compositing.

Window manager spec

The EWMH window manager specification, also known as NETWM, is located at the freedesktop.org site, http://standards.freedesktop.org/wm-spec/wm-spec-latest.html. It defines how the window manager communicates information with the applications and other desktop utilities such as the taskbar or pager.

Notes

So, you feel brave, huh? But KWin is not THAT difficult. Some parts, especially the X-related ones, can be very complicated, but for many parts even knowledge of X and Xlib is not necessary. Most X code is wrapped in helper functions. However, although many features don't require touching X/Xlib directly, still X/Xlib may impose their semantics on the way things are done. When in doubt, simply ask.

All merge requests for KWin should be sent to GitLab for review first. Even seemingly harmless changes may have extensive consequences. For more information, see Infrastructure/GitLab.

Various notes:

  • kDebug has overloaded operator << for the Client class, so you can e.g. use 'kDebug() << this;'

in class Client and it will print information about the window.

  • KWin itself cannot create any normal windows, because it would have trouble managing its own windows. For such cases (which should be rare) a small external helper application is needed (kdialog should often do, and for special cases such a utility needs to be written like kwin/killer).

Coding style

KWin follows the kdelibs coding style.

The source repository was reformatted with git commit 4fd08556.

Submitting Changes

KWin development uses ReviewBoard for code review. Upload your change for the repository "kwin" (for 4.11 it's "kde-workspace") and add review group kwin.

Documentation

X documentation

As already said, many parts of KWin don't need knowledge of Xlib or even how X actually works. Some parts do, and it may be also useful to have at least a basic understanding for general understanding. A reference manual for Xlib can be found e.g. at ftp://ftp.x.org/pub/X11R7.0/doc/PDF/xlib.pdf , a tutorial explaining basic can be found e.g. at http://users.actcom.co.il/~choo/lupg/tutorials/xlib-programming/xlib-programming.html (note that you don't need to know that all - e.g. GC's are very rarely needed and the section on fonts is today outdated). At http://www.sbin.org/doc/Xlib/index_contents.html can be found an Xlib programming manual (some of those are more or less obsolete these days, but there is e.g. an extensive section related to window management).

OpenGL

KWin uses OpenGL for its compositor and in some effects. Most effects do not use OpenGL directly, so it is possible to write effects without the knowledge of OpenGL. If you want to directly manipulate the rendering scene or working on the Compositor itself you must have at least some basic knowledge about OpenGL.

OpenGL comes in two different flavors: fixed functionality and programmable pipeline. There are several versions of OpenGL. OpenGL 1.x only supports fixed functionality, OpenGL ES 2.0 and OpenGL 3/4 (forward compatible profile) only supports programmable pipeline. OpenGL 2.x supports both way of programming.

KWin has code paths for both fixed functionality and programmable pipeline. By default, KWin uses programmable pipeline and only falls back to fixed functionality if the GPU does not support it. New code should focus on programmable pipeline and restrict itself to the OpenGL ES 2.0 API.

Books

There are various books about OpenGL, documenting different bits of the API

  • OpenGL Programming Guide - The Redbook The online resource is the (outdated) 5th edition not covering OpenGL Shading Language. Even the 6th edition does only contain a small chapter on OpenGL Shading Language and the previous chapters are slightly outdated, too. Nevertheless it's a good book for learning the concepts of OpenGL, but does not help much on KWin development.
  • OpenGL Shading Language a good book about OpenGL Shading Language. In the 2nd edition it was strongly focusing on extending the fixed functionality with some programmable states. It seems that in the 3rd edition it got updated to using only shaders. The examples might be too extensive for use in KWin.
  • OpenGL SuperBible This is one of the best books for OpenGL development. The 4th edition has an extensive view on both fixed functionality as well as programmable pipeline. In the 5th edition fixed functionality has been completely removed and the book has been rewritten for programmable pipeline with OpenGL 3. The book is well structured and has a good teaching approach. One of the best features is the API documentation in the Appendix.

API Documentation

Finding the right API documentation for OpenGL is rather difficult. KWin uses in general functionality from OpenGL 2.1 but also uses some functionality provided by Extensions. The programmable pipeline code path should be compatible with OpenGL ES 2.0, this means it is not allowed to use fixed functionality API calls, even if listed in the OpenGL 2.1 reference pages.

  • OpenGL 3.3 Reference Pages These man pages only document the core context.
  • OpenGL 2.1 Reference Pages Complete OpenGL 2.1 API including GLX. This includes both fixed functionality and programmable pipeline. Do not use any API call only available since OpenGL 2.0 in the fixed functionality code path and do check whether an API call is still available in the OpenGL 3.3 core context for the programmable pipeline path
  • OpenGL ES 2.0 Reference Pages Subset of OpenGL 2 for embedded devices. Best restrict to this API in the programmable pipeline path. Any API call not available in OpenGL ES 2.0 will fail when compiling against OpenGL ES.