Development/Tutorials/KWin/WindowSwitcher
Introduction
The Window Switcher (Alt+Tab) can be custom styled using layouts written in QML since KDE Plasma Workspaces in version 4.8. The window manager supports multiple Window Switcher and exchanges the loaded layout at runtime. Additionally the underlying Model is recreated each time the switcher is invoked and some properties might change due to screen changes and different settings for the multiple switchers. To support this the QML loader can set properties in the custom QML component if available.
Global Properties
- int screenWidth: the width of the primary screen. This property can be used to restrain the width of the switcher to the current screen.
- int screenHeight: the height of the primary screen. This property can be used to restrain the height of the switcher to the current screen.
- string longestCaption: the window title with most characters at the moment of Model creation. This property can be used to dynamically calculate the width of a list view based on the longest window title.
- bool allDesktops: whether the Model includes windows from all desktops or only the current desktop. This property can be used to e.g. hide the desktop a window is on when the switcher only shows windows of the current desktop. Do not use this property to filter the list. This is done by the Model.
If the custom QML layout supports the same properties on the root item, they will be set whenever the layout is loaded and whenever the value changes.
Model
The Model is available as a context property clientModel. Additionally the custom component can define a function called setModel(model) which is invoked whenever the Model is set. By that the QML layout can react on the expected Model changes. The component can also define a function called modelChanged() which gets invoked whenever the Model is reset. This happens for example when a window closes while the window switcher is active.
The Model provides the following roles:
- string caption: the window title
- bool minimized: whether the window is minimized
- string desktopName: the name of the desktop the window is on
- ulonglong windowId: the window Id (XId) of the window
Icon
The window switcher includes an Image Provider to return the window's icon. An image url looks like the following:
image://client/<index>/<invokation-uid>
The URL supports an additional suffix /selected to request a highlighted item or /disabled to request an icon in disabled look. E.g.
image://client/1/1223-324/disabled
It is important to remember that QML caches the icons. As the URL is based on the Model index which changes from each invocation of the window switcher a unique Id has to be added to disable the cache. This unique Id should be changed whenever the modelChanged() function described above is invoked.
Model based View
The window switcher has to set the index in the list view to select the proper item when the switcher is invoked. Because of that the ListView implementation has to follow this contract:
- Property objectName must have value listView
- a signal currentIndexChanged(int index) must be defined and invoked whenever the ListView changes the index (e.g. due to mouse click).
Thumbnails
The window manager provides a QML component to render a live thumbnail of the window. It is important to know that this thumbnail is not rendered in QML's scene graph, but by the compositor after the window has been rendered. Because of that it is not possible to put other visual components on top of the thumbnail. If compositing is not available an icon will be rendered instead of the thumbnail.
To use the Thumbnail component import org.kde.kwin in version 0.1. The component is called ThumbnailItem and has one required property wId. Example
import QtQuick 1.0
import org.kde.kwin 0.1 as KWin
ListView {
objectName: "listView"
model: clientModel
delegate: KWin.ThumbnailItem {
wId: windowId
width: 200
height: 200
}
}
Installation
In 4.8 the installation of the custom layouts is not optimal. This will change for the next release. The QML file(s) has to be stored in ~/.kde/share/apps/kwin/tabbox/. Unfortunately the configuration module does not yet recognize custom layouts. To enable the layout use:
kwriteconfig --file kwinrc --group TabBox --key LayoutName <nameoflayout>
The layout name is the name of your main QML file without the suffix and only small letters. E.g. MyLayout.qml becomes mylayout. To set the alternative switcher use TabBoxAlternative instead of TabBox. Now KWin has to reload the settings (change anything in a KCM) or has to be restarted.