-
-
Notifications
You must be signed in to change notification settings - Fork 591
Window states management
These are window states tracked by the X server. They might or might not be stored directly in struct managed_win
.
Name | Description | Availability in events |
---|---|---|
Properties | Window properties, the ones you can view with xprop
|
PropertyNotify , only tells us if the property is changed or deleted, new property value not included |
Attributes | Window attributes | Unavailable, but we also don't care. Except for the backing_pixmap of the root window, which is available via property, _XROOTPMAP_ID or _XSETROOT_ID
|
Geometry | Window size and position |
ConfigureNotify , fully available. But this information is only needed when rendering, so we could aggregate updates between renders |
Shape | Shape of a non-rectangular window |
ShapeNotify , only tells us if the shape is changed, new shape not included |
Viewability | Whether a window is mapped, is viewable |
MapNotify and UnmapNotify , fully available. But all of the other states of a newly mapped window won't be available |
Focus | Whether a window has input focus |
FocusIn and FocusOut , fully available. But also affected by the _NET_ACTIVE_WINDOW property,
so can't update in the event handler |
There are also states concerning relationships between windows
Name | Description | Availability in events |
---|---|---|
Stacking order | The order of how windows are stacked on top of each other |
ConfigureNotify and CirculateNotify , fully available |
Hierarchy | The tree structure formed by X windows. picom only really cares about toplevel windows, but we still need to keep track of hierarchy changes |
ReparentNotify , fully available. But if a previously non-toplevel window becomes toplevel; or if a previous child of an unviewable window is reparented to a viewable window, all of its other states won't be available |
Each of these states almost directly corresponds to a raw window state. They are stored in the struct manage_win
.
Name | Description | Source |
---|---|---|
name | ICCCM/EWMH window name | Property, _NET_WM_NAME and WM_NAME
|
g | Window geometry | Geometry |
stacking_rank | Number of windows above current window | Stacking order |
bounding_shape | Shape | |
bounding_shaped | Whether the current window is Shaped | Shape |
window_type | EWMH window types | Property, _NET_WM_WINDOW_TYPE
|
leader | ICCCM window group leader | Property, WM_CLIENT_LEADER and WM_TRANSIENT_FOR
|
class_instance, class_general |
ICCCM window classes | Property, WM_CLASS
|
role | ICCCM window role | Property, WM_WINDOW_ROLE
|
opacity_prop | Desired opacity of window | Property, _NET_WM_WINDOW_OPACITY (not in EWMH),can be set on the WM frame, or on the client window |
frame_extents | Size of the window manager frame | Property, _NET_FRAME_EXTENTS
|
prop_shadow | Whether a shadow is desired for this window | Property, _COMPTON_SHADOW
|
client_win | The client window of the window manager frame | Hierarchy |
These states are derived from raw X states.
These states aren't influenced by the user directly
Name | Description | Source |
---|---|---|
state | Mostly correspond to X window states (mapped/unmapped/etc.), but because of fading, also includes transitional states |
Viewability |
mode | Whether the window is transparent, frame transparent, or completely opaque | Property, and window pixel format |
in_openclose | Whether the window is in open/close state, in other words, whether the window is mapped for the first time, or just destroyed. |
Viewability |
opacity | Current window opacity |
state , and fading progress |
opacity_target | Target window opacity |
state (??) |
User can change these states via DBus
- fade_force
- shadow_force
- invert_color_force
- focused_force
Options themselves can't change, only change in other factors would cause these states to change.
Name | Option |
---|---|
corner_radius (#480) | |
frame_opacity | frame-opacity |
shadow_opacity |
frame-opacity , and shadow-opacity
|
shadow_dx, shadow_dy, shadow_width, shadow_height |
various shadow options |
dim |
inactive-dim , and current window state, and Focus |
All rule based states also derive from window Properties.
Name | Description | Source |
---|---|---|
opacity_is_set, opacity_set |
user defined opacity value | opacity-rule |
fade_exclude | fade-exclude |
These states are influenced by rules, as well as other window states and other options
Name | Description | Source |
---|---|---|
invert_color | Rule: invert-color-include Other states: invert_color_force
|
|
shadow | Rule: shadow-exclude ,Options: wintypes.xxx.shadow , shadow-ignore-shaped Other states: shadow_force , prop_shadow
|
|
widthb, heightb | Window size, including the shadow if there is one | Geometry, shadow , shadow_{dx,dy,width,height}
|
blur_background | Rule: blur-background-exclude ,Options: wintypes.xxx.blur-background
|
|
focused | Focus, Rule: focus-exclude Options: mark_ewmh_focused , mark-ovredir-focused , wintypes.xxx.focus Other states: focused_force
|
Image data used for rendering, invalidated when some of the other window states change.
Name | Description | Source |
---|---|---|
shadow_image | backend dependent image data for the shadow | Geometry, shadow , ??? |
image | backend dependent image data for the window itself | Geometry, ??? |
Window state changes start from ev_handle
, which handles events sent by the X server. ev_handle
will update window states from what is available in the event itself, then mark the window for further processing in the X critical section.
Information stored in the X server has to be queried in the X critical section, otherwise we are prone to race conditions with other X clients.
In the X critical section, window states should be updated in this order:
- Client windows of window manager frames are updated based on hierarchy information. This is done first, because later updates might require accurate client window information.
- Window size, position and shape are updated, and added to damage.
- Updated properties are retrieved from the X server. Mirrored states based on the properties will be updated. (XXX: would window size/shape depend on properties?)
- Rules are re-evaluated
- All other states are updated accordingly.
There is a special case, where a window receives a bunch of updates, and is then destroyed before the next X critical section. ev_handle
will initiate the destroy sequence (fade out, etc.), and that should clear some (or all?) of the updates previously queued by ev_handle
, because none of the raw window states will be available from X after the window is destroyed.
Above is generally true for visible (or viewable, in Xorg terms) windows, however, if a window is not visible, we don't really need to keep its states up-to-date, as it won't be seen anyway.
Essentially, in ev_handle
, all window will be treated the same, visible or not. But updates queued by ev_handle
won't be processed if the window is not visible, and will be processed all at once when the window become visible. This way we don't need take special care around these windows in state update functions, and should make things easier to reason about.
But this creates a chicken and egg problem: if we don't process updates, how could we know if a window has become visible? To solve this problem, we have to declare a set of window states to be "visibility related", and will be updated for all windows. If we want to get philosophical about what actually is "visibility related", things will get really complicated. So right now we only treat the state
variable as visibility related.
If a window is UNMAPPING
, UNMAPPED
, or DESTROYING
, it should be treated as not visible; otherwise it is visible. Transitional states are a bit tricky, but I think this is correct. An unmapping or destroying window should retain its last appearance. In other words, the window itself is not visible anymore, what the user sees is an illusion presented by the compositor.
Everything in this wiki is published under the CC BY-SA 4.0 license. You can find the license text here