Skip to content

Per-monitor task lists, multi-row task buttons, task button drag reordering - #680

Open
gpertea wants to merge 8 commits into
joewing:masterfrom
gpertea:multimonitor-taskbars
Open

Per-monitor task lists, multi-row task buttons, task button drag reordering#680
gpertea wants to merge 8 commits into
joewing:masterfrom
gpertea:multimonitor-taskbars

Conversation

@gpertea

@gpertea gpertea commented Jul 26, 2026

Copy link
Copy Markdown

This adds native multi-monitor taskbar support, building on JWM's existing screen-bound tray placement (<Tray screen="N">). All new behavior is opt-in via jwmrc attributes, adds no new hard dependencies (XRandR is optional and
--disable-xrandr-able). Documented in jwm.1.in.

Features:

  • <TaskList screen="local"/>: a task list shows only clients whose
    dominant (largest-overlap) Xinerama screen is the screen of its
    containing tray; screen="all" (default) is the previous behavior
    and a numeric value selects an explicit screen. With one tray per
    monitor this gives a per-monitor taskbar on each screen showing
    only that screen's windows.
  • Task buttons follow windows across monitors: the dominant screen is
    cached on the client and re-evaluated on every configure, so a
    window dragged to another monitor migrates to that monitor's bar
    (appended at the end).
  • <TaskList rows="N"/>: multi-row task buttons on horizontal trays
    (row-major layout; N=1, the default, renders exactly as before).
  • <Tray screen="DP-2"> / <Tray screen="primary">: with the new
    optional XRandR support, active CRTC rectangles are matched to the
    Xinerama screens by geometry at startup so trays can reference
    screens by output name; unknown names warn and fall back to
    screen 0. No RandR event handling is added; the configuration is
    re-read on restart as usual.
  • Drag reordering of task buttons (left-drag; a plain click still
    activates/minimizes as before, now acted on button release). As
    part of this, DiscardButtonEvents no longer discards queued button
    releases, which could break press/release pairing for components
    with a release handler.

Tested under Xephyr multi-head and in daily use on a 4-monitor Ubuntu 24 desktop (including a rotated portrait monitor).

gpertea added 8 commits July 24, 2026 12:04
Warn and clamp to screen 0 when <Tray screen="N"> exceeds the number
of Xinerama screens. Fix stale comment (default is 0, not -1). Ignore
autotools-generated files.
Add GetDominantScreen() (largest-overlap Xinerama screen, midpoint
fallback) and a screenIndex cache on ClientNode, recomputed in
SendConfigureEvent. A screen change triggers RequireTaskUpdate so
screen-bound taskbars can refresh; behavior-neutral until a taskbar
uses the screen filter.
New TaskList attribute screen="all|local|<index>" (default all, the
previous behavior). With "local" a task bar shows only clients whose
dominant screen is the parent tray's screen; a numeric value selects an
explicit Xinerama screen. Filtering composes with the existing desktop
gate; grouped entries appear on any bar with a member on that screen
and the group count label counts only local members. Buttons migrate
between bars when a window is moved across screens (via the cached
screenIndex update in SendConfigureEvent).
New TaskList attribute rows="N" (1-8, default 1). Buttons are placed
row-major; item height divides the bar height by the row count and the
column count follows from the visible item count. A single row keeps
the previous layout since the column count then equals the item count.
Click/popup hit testing shares the same row-major math.
When a client's dominant screen changes, move its task entry to the
end of the global task list so its button is appended after the
existing buttons on the new screen's bar. Previously the button
landed wherever the window's creation time fell in the global order
(sometimes first, sometimes mid-list). No-op unless some task bar
uses a screen filter, so unfiltered configurations keep the upstream
stable ordering.
New --enable-xrandr (on by default when Xinerama is available): at
startup, active CRTC rectangles are matched to the Xinerama screens
by exact geometry and the output names (and primary flag) recorded.
<Tray screen="DP-2"> and <Tray screen="primary"> then work in
addition to numeric indices; names are resolved in StartupTray since
screens are unknown at parse time, with warning + screen 0 fallback.
No RandR event handling; the layout is re-read on restart.
Left-press on a task button now arms a drag (with a pointer grab on
the tray); moving past the double-click delta enters drag mode and
the pressed entry is moved next to whichever entry the pointer
crosses, in all layouts (multi-row included). The classic click
action (activate/minimize the group) runs on button release when no
drag occurred, so plain clicks behave as before. DiscardButtonEvents
now discards only presses: eating a queued release broke press/
release pairing for components with a release handler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant