Configuration¶
Configuration Files¶
The configuration of Chamferwm is managed through a Python script. The provided configuration script defines the necessary classes and routines for layout management and overall behaviour of the window manager. For basic customization, user may want to edit the default configuration script to (re)define key bindings and add calls to launch applications and such. More advanced configuration might enhance the window management through provided callbacks, set up shaders to customize visuals and introduce other means to alter the behaviour and provide features.
By default Chamferwm will look for the configuration in following locations:
~/.config/chamfer/config.py
~/.chamfer/config.py
/usr/share/chamfer/config/config.py
The path to the configuration script can also be given with --config=[path]
, which will override any previously found files.
In the official setup, a default configuration script has been installed to /usr/share/chamfer/config/
as a starting point for customization. User may want to copy this file to the previously listed locations in order to start editing. Currently any modification will require a restart of the window managar to take effect.
Warning
While the configuration API is still unstable, and new features are being added, default configuration will be subject to minor changes.
Changing shortcuts¶
Some typical operations have already been assigned a key combination in the provided default configuration. The bound operations are listed under Key(Enum)
class, where an identifier has been given to each of them. The corresponding lines to define the actual key combinations can be found futher below, under a callback chamfer.Backend.OnSetupKeys()
. For each binding, one finds
self.BindKey(symbol, mask, keyId)
Here symbol is the keysym code for the desired key. A list of symbols can be found inside a header file /usr/include/X11/keysymdef.h
, for example. mask defines the modifier mask for the key combination. Possible modifiers are:
chamfer.MOD_MASK_SHIFT
chamfer.MOD_MASK_CONTROL
chamfer.MOD_MASK_LOCK
chamfer.MOD_MASK_ANY
chamfer.MOD_MASK_1
chamfer.MOD_MASK_2
chamfer.MOD_MASK_3
chamfer.MOD_MASK_4
chamfer.MOD_MASK_5
Run xmodmap -pm
to find out which key each of the mask corresponds to on your system. The last argument keyId is the identifier defined under previously mentioned Key(Enum)
. The identifier will be used to map a key press to an operation written in chamfer.Backend.OnKeyPress()
and chamfer.Backend.OnKeyRelease()
.
In order to change the key binding for launching a terminal emulator for example, one should look for a self explanatory definition LAUNCH_TERMINAL
, and the corresponding BindKey()
entry, for which the parameters should be changed.
Launching Applications¶
Setting up an application launcher in case of Chamferwm consists of two steps: 1) defining the key binding and 2) adding callback functionality (corresponding the key binding) to start the said application. In this example we set up a hotkey to launch a web browser.
1. Application hotkey. First step is to bind the key which we want to launch the browser. Our choice of key combination in this example is Super+1. We add the following line under callback chamfer.Backend.OnSetupKeys()
already found in the default configuration as a method of Backend
class:
self.BindKey(ord('1'),chamfer.MOD_MASK_4,Key.LAUNCH_BROWSER.value)
Here chamfer.MOD_MASK_4
corresponds the modifier mask of the Super key. The last parameter takes our custom identifier of the hot key we are in process of defining. The identifier will be passed on to the key press callback chamfer.Backend.OnKeyPress()
and it should be uniquely defined somewhere. We may define it using enum.Enum
and enum.auto()
so that it automatically receives an incremented unique value. In our default configuration we add:
class Key(Enum):
...
LAUNCH_BROWSER = auto()
...
2. Launch procedure. We launch the application using psutil
module's psutil.Popen()
function. Under chamfer.Backend.OnKeyPress()
callback we add a branch for our newly defined key identifier, in which we start our browser process:
elif keyId == Key.LAUNCH_BROWSER.value:
psutil.Popen(["firefox"],stdout=None,stderr=None);
Note that it is possible to configure applications to launch on start up while the window manager is being initialized. In this case simply put psutil.Popen()
somewhere in the global scope.
Any other functionality can be added similarly. Instead of calling psutil.Popen()
to launch a browser, any other routine can be written in place of this. Writing routines in Python inside the same configuration file eliminates the need for smaller separate utility scripts often placed to complement to configuration file itself.
Python API¶
Warning
Chamferwm is work in progress, and the configuration API is subject to breaking changes. The default configuration file config.py may also undergo additions and minor refactoring.
- class chamfer.Container¶
The workspace in Chamferwm is arranged in containers. Containers are a construct to hold either a client window or a set of child containers. The concept of a child container comes from a hierarchial approach: at the base of the tree, there exists a root container which is split into one or more child containers. The child containers may in turn be further split into child containers, or alternatively hold a single instance of a client window.
The
Container
class is a user implemented interface to define callbacks related to creation and initialization of the container and client window, and to handle events that might arise during window management.- OnSetupContainer()¶
Called to setup the container before it is created. One should setup
minSize
,maxSize
andfloatingMode
here, if necessary.
- OnSetupClient()¶
Called to setup the client before it is created. Can be especially used to assign the initial shaders
vertexShader
,geometryShader
andfragmentShader
.
- OnParent()¶
Called to assign a parent for the container. The parent is assigned by returning the
Container
instance of the desired parent. Most of the timeOnParent()
is called upon creation of a new container, as it needs to be put into a parent container. In the default sample configuration, the parent of the operand will be the parent of the current focus (retrieved usingchamfer.Backend.GetFocus()
), resulting in the new container being placed next to the current focus.
- OnCreate()¶
Called once the client has been created and mapped to the display. Typically the newly created client can now be focused by calling
Focus()
.
- OnFullscreen(toggle)¶
Called to request permission to enter or exit fullscreen mode for this container depending on the value of toggle. The implementation should return true on permission granted, and false for permission denied. In addition, one may assign a different set of shaders that may better benefit the fullscreen mode, and perform other operations related to the preparations for the transition.
- OnStack(toggle)¶
Called whenever containers under this container are stacked or unstacked, denoted by toggle.
- OnFocus()¶
Called to request permission for focus, and to allow for any routines before it. This call may be a result of calling
Focus()
, or a client spontaneously requesting it. Returning true assigns the focus on this container.
- OnPropertyChange(propId)¶
Called every time a client property has changed. This may refer to window title etc., given by propId, which will have one of the values from
property
.
- GetNext()¶
Get the next sibling container in the parent container.
- GetPrev()¶
Get the previous sibling container in the parent container.
- GetParent()¶
Retrieve the parent container.
- GetFocus()¶
Get the focused container of the parent container. This will be one of the child containers of the operand.
- GetTiledFocus()¶
Get the most recently focused tiled container. Successive calls on the return objects, for example
container.GetTiledFocus().GetTiledFocus()...
, will retrieve the second most recent, third most recent and so on container.
- GetFloatFocus()¶
Get the most recently focused floating container.
- GetAdjacent()¶
reserved
- MoveNext()¶
Swap this and the next sibling container.
- MovePrev()¶
Swap this and the previous sibling container.
- Move(container)¶
Move this container under to a new parent, container.
- Focus()¶
Focus the container. If the container is in another workspace, a workspace switch will occur. Changing workspaces is also possible by focusing the root container of the target workspace.
- Kill()¶
Close the client and kill the container.
- ShiftLayout(layout)¶
Shift the container layout to a new layout indicated by
layout
. Most prominently used to transition between vertical and horizontal container splittings. May also be used to force some of the changed container parameters to take effect, such as changes tocanvasOffset
etc., whicn for performance reasons will not result in an automatic update.
- SetFullscreen(toggle)¶
Move this container to a fullscreen mode, or back to normal depending on the value of toggle (true, false).
- SetStacked(toggle)¶
Toggle container stacking inside this container. If
layout
is equal tochamfer.layout.VSPLIT
, the containers will be tabbed, and can be cycled horizontally. Otherwise, the containers are stacked, and are vertically cycled.
- SetFloating(toggle)¶
Toggle between tiled and floating modes.
- IsFloating()¶
Returns true if this is a floating container.
- IsAlive()¶
Returns true if the container still exists, i.e. it has not been removed. Use of a removed container will raise an exception.
- name¶
Name label of the container. Workspaces are identified by their root container name label.
- canvasOffset¶
Tiled container position offset. This is a tuple of two values between 0 and 1 for horizontal and vertical directions, indicating the position offset of the container in the units of full screen widths/heights. A value of zero implies no offset, while a value of 1 displaces the container one full screen width or height. As an example, a value of
(-0.1,0)
implies a displacement of 10% of the screen width to the left.
- canvasExtent¶
Tiled container size extension. See
canvasOffset
for details. In this case, a value of(-0.1,0)
would imply a contraction of 10% of the screen width towards the left side of the container. Likewise(0,0.2)
expands the container vertically 20% of the screen height downwards.
- margin¶
A tuple of two values, one for horizontal and vertical screen dimensions. A positive non-zero value will apply a gap between the containers in order to give the compositor space to render the decorations around the client windows. The units are in full screen widths (and widths only, to preserve the aspect). Setting
margin = (0.015,0.015)
would inset the container by 1.5% of the screen width horizontally and vertically.
- size¶
A tuple of two values for the size of the container and space reserved in horizontal and vertical screen direction. The units are widths and heights of the parent container: for instance, a value of
(0.7,1)
reserves 70% of the total horizontal and 100% of the vertical space given by the parent. If only one container exists, the value will always be(1,1)
. The value is automatically updated as the surrounding layout changes. For example, the first container will have a size of(1,1)
. Creating a second container will split the space in half, giving both containers a size(0.5,1)
(in case of vertical splitting). User may then adjust the size of one of the containers to(0.7,1)
, which will automatically assign the other container a size(0.3,1)
.
- minSize¶
Minimum size that the container may shrink to while making space for other containers. A tuple of two values, one for the each dimension of the screen. The units are widths and heights of the full screen.
minSize
of(0.3,0)
will always keep the container width at least 30% of the full screen width, while(1,0)
will make the container always occupy the full width of the screen. In case the space within the parent container runs out, containers will automatically start overlapping each other in a stacking manner.
- maxSize¶
Maximum size that the container may expand to when there is space available. See
minSize
for details.
- fullscreen¶
Read only fullscreen status: true if this container is in fullscreen mode, false otherwise.
- stacked¶
Read only container stacking status: true if containers inside this container are stacked.
- shaderFlags¶
User supplied value that will be passed on to the shaders as a push constant. See
shaderFlag
for the list of bit flags automatically managed by Chamferwm. Note that all bits belowUSER_BIT
are reserved for use by Chamferwm.
- wm_name¶
Current title of the client window. Read only.
- wm_class¶
Current class name of the client window. Read only.
- vertexShader¶
File name of the vertex shader to be used to render this client. The name of the file will be matched to the files found in the shader lookup directories. Default
vertexShader = "default_vertex.spv"
.
- geometryShader¶
File name of the geometry shader. See
vertexShader
for details.
- fragmentShader¶
File name of the geometry shader. See
vertexShader
for details.
- layout¶
Current tiling layout of the container. One of the values from
chamfer.layout
. Layout transitions are handled by callingShiftLayout()
with the desired new layout. By default, the container will be created inchamfer.layout.VSPLIT
mode.
- floatingMode¶
Determine in which mode (tiled or floating) the client shall be created. See
floatingMode
for possible values. Default =AUTOMATIC
.
- class chamfer.layout(enum.Enum)¶
Possible values of
layout
and the layout parameter ofShiftLayout()
, dictating the splitting mode of the container.- VSPLIT¶
Implies a vertically split container. Containers will be placed in a horizontal row.
- HSPLIT¶
Implies a horizontally split container. Containers will be placed in a vertical column.
- class chamfer.floatingMode(enum.Enum)¶
Possible values of
floatingMode
, dictating the mode in which the client shall be created.- AUTOMATIC¶
Whether the client will be created in a floating or tiled mode will be determined automatically from its client attributes.
- ALWAYS¶
The client is always created in floating mode, regardless of its client attributes.
- NEVER¶
The client is always created in a tiled container, regardless of its client attributes.
- class chamfer.property¶
Various client property identifiers.
- NAME¶
Client window title.
- CLASS¶
Client window class name.
- class chamfer.titleBar¶
Title bar placement. By default the title bars are placed on top of the client.
- NONE¶
Hide title bar
- LEFT¶
Title bar placed at the left border of client
- TOP¶
Title bar placed at the left border of client
- RIGHT¶
Title bar placed at the left border of client
- BOTTOM¶
Title bar placed at the left border of client
- class chamfer.Backend¶
A user implemented interface to define routines for various window management related events. Moreover,
Backend
provides methods for ...- OnSetupKeys(debug)¶
Called as soon as the backend is initialized. Ideal for setting up the keybindings for example. debug will tell if testing backend (not a real window manager) was created.
- OnCreateContainer()¶
Called to request a new instance of
Container
. The implementation is expected to return an instance of this class.
- OnKeyPress(keyId)¶
Called to report a press of a key that was mapped with either
Backend.BindKey()
orBackend.MapKey()
. keyId is the user chosen identifier for the reported key.
- OnKeyRelease(keyId)¶
Called to report a release of a key. See
Backend.OnKeyPress()
.
- OnTimer()¶
reserved
- OnExit()¶
Called when user quits the window manager.
- GetFocus()¶
Get the currently focused container
chamfer.Container
.
- GetRoot(name=None)¶
Get the root container
chamfer.Container
. If name is specified, return the root container belonging to that workspace. Otherwise return the root of the currently focused container. If workspace does not exist, it will be created.
- BindKey(symbol, mask, keyId)¶
Bind key symbol with modifier mask. The key combination will be exclusive to Chamferwm, and won't be reported to any of the clients. Whenever the bound key is pressed,
chamfer.Backend.OnKeyPress()
with keyId is called. Likewise,chamfer.Backend.OnKeyRelease()
is called when the pressed key is released.
- MapKey(symbol, mask, keyId)¶
Unlike
chamfer.Backend.BindKey()
, mapped keys are not exclusive to Chamferwm, and not reported untilchamfer.Backend.GrabKeyboard()
is called. Seechamfer.Backend.GrabKeyboard()
for details.
- GrabKeyboard(enable)¶
Once keyboard is grabbed, keys mapped using
chamfer.Backend.MapKey()
besides the other key bindings are reported. During this, no key input whatsoever will be reported to the clients. GrabKeyboard method is useful for implementing functionality such as task switcher, which could be operating for as long as some modifier key is being held down.
- chamfer.BindBackend(backend)¶
Bind your instance of
Backend
class implementation, assigned by a call toBindBackend()
. Should be done during initialization.
- chamfer.backend¶
Bound backend class object used by Chamferwm. Read only attribute.
- class chamfer.shaderFlag(enum.Enum)¶
Bit flags for the shader push constant, accessible with
shaderFlags
.- FOCUS¶
Client focus bit, set automatically by Chamferwm.
- FLOATING¶
Floating client bit, set automatically by Chamferwm.
- STACKED¶
Stacked client bit, set automatically by Chamferwm.
- USER_BIT¶
First bit reserved for user defined flags.
- class chamfer.Compositor¶
A user implemented interface to define routines for various compositing related events.
- deviceIndex¶
GPU to use by its index. By default the first device in the list of enumerated GPUs will be used. May be overriden by command line arguments.
- debugLayers¶
Enable Vulkan debug layers. May be overriden by command line arguments.
- scissoring¶
Enable or disable scissoring optimizations. By default the optimization is enabled. If during compositing missing regions or flickering occur, the scissoring optimization can be disabled. The option
--no-scissoring
forces this false.
- hostMemoryImport¶
Host shared memory import support.
- unredirOnFullscreen¶
Disable compositor while on fullscreen (not implemented).
- enableAnimation¶
Enable or disable transition and movement animations. Enabled by default.
- animationDuration¶
Total duration of the transition and movement animations. Default 0.3 seconds.
- fontName¶
Font face to use for title bars.
- fontSize¶
Title bar font size in points.
- chamfer.BindCompositor(compositor)¶
Bind your instance of
Compositor
class implementation. Should be done during initialization.
- chamfer.compositor¶
Bound compositor class object used by Chamferwm, assigned by a call to
BindCompositor()
. Read only attribute.