Skip to content

Per-monitor layout matching #214

Description

@MarcinOrlowski

This change lets a layout declare which monitors it is supposed to be used with, as each screen only offers the layouts that make sense there. Matching entirely optional and fully transparent unless explicitly used in configuration as if no matching criteria is set, then it means all is allowed.

A layout can carry an optional match object that holds set of various criteria that are evaluated to see if layout can be offered for specific monitor. You can have loose criteria (like orientation) as well as resolution up to hardware display name. Every criterion present must match; if given match parameter is not given it means it does not contribute to filtering (like it passes any element). That approach and file format change allows easy expansion, new filters and additions to be incorporated w/o breaking backward compatibility.

Supported matches:

  • display - display output name, or a list of them: "DP-4" or ["DP-1", "HDMI-A-1"]. * is a wildcard ("DP-*"), matching is case-insensitive. If no display is specified, layout is considered a match for any display.
  • resolution - WIDTHxHEIGHT in pixels, or a list of resolutions. Wildcards allowed ("1920x*"). This is the rotated resolution, so a pivoted 1920x1080 monitor is "1080x1920"!
  • orientation - horizontal or vertical. A screen is vertical when it is taller than it is wide, so this follows a monitor as it is rotated.

Example resolution:

  {"resolution": ["3840x2160", "1920x1080"]}
      FHD 1920x1080           MATCH
      4K 3840x2160            MATCH
      UW 3440x1440            no

  {"resolution": ["1920x*", "*x1440"]}          ← wildcards inside a list
      FHD 1920x1080           MATCH
      FHD pivoted 1080x1920   no                ← rotated, so no longer 1920-wide
      UW 3440x1440            MATCH

  {"display": ["DP-*"], "resolution": ["3440x1440", "2560x1080"]}
      DP-1 3440x1440          MATCH
  NoteHDMI-A-1 3440x1440      no                ← display rejects it

Resolution and orientation are read from the output's own geometry, not the usable area, so panels and docks do not affect them.

[
  {
    "name": "Ultrawide thirds",
    "match": {
      "display": "DP-1"
    },
    "zones": []
  },
  {
    "name": "Wide bars",
    "match": {
      "orientation": "horizontal"
    },
    "zones": []
  },
  {
    "name": "DP tall",
    "match": {
      "display": "DP-4",
      "orientation": "vertical"
    },
    "zones": []
  },
  {
    "name": "Everywhere",
    "zones": []
  }
]

PR attached.

This work also addresses the following tickets:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions