feat: size: prefix, external auto-detection, auto-disable stale monitors
- size:WxH and size:WxH@R resolution for config names - auto-detection of external monitors when external list is empty (any non-internal display) - ensureCleanLayout: explicitly disable connected monitors not in target layout - update docs (README, example.yaml) for all three features
This commit is contained in:
+29
-10
@@ -157,10 +157,8 @@ func (c *Config) validate() error {
|
||||
if countEnabled(docked.Monitors) == 0 {
|
||||
return errors.New("docked mode must have at least one enabled monitor")
|
||||
}
|
||||
// At least one external monitor must be listed.
|
||||
if len(c.External) == 0 {
|
||||
return errors.New("at least one external monitor must be specified")
|
||||
}
|
||||
// External list is optional. When empty, the daemon auto-detects
|
||||
// external monitors (any non-internal display with non-zero dimensions).
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -195,19 +193,40 @@ func countEnabled(entries []MonitorEntry) int {
|
||||
return n
|
||||
}
|
||||
|
||||
// MatchesExternal checks whether a monitor name or description matches any
|
||||
// entry in the External list. Supports two match modes:
|
||||
// isInternalConnector returns true if the connector name matches a known
|
||||
// internal display pattern (eDP, LVDS, DSI). These are always part of the
|
||||
// laptop or tablet and should never trigger docked mode.
|
||||
func isInternalConnector(name string) bool {
|
||||
prefixes := []string{"eDP-", "LVDS-", "DSI-", "EDP-"}
|
||||
for _, p := range prefixes {
|
||||
if strings.HasPrefix(name, p) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MatchesExternal checks whether a monitor matches the External list.
|
||||
// Supports match modes:
|
||||
//
|
||||
// - Plain name: exact match against MonitorEntry.Name
|
||||
// - desc: prefix: substring match against MonitorEntry.Description
|
||||
// - Plain name: exact match against name
|
||||
// - desc: prefix: substring match against description
|
||||
//
|
||||
// When the External list is empty, any monitor that is not an internal
|
||||
// display connector (eDP-, LVDS-, DSI-) is automatically external.
|
||||
func (c *Config) MatchesExternal(name, description string) bool {
|
||||
if len(c.External) == 0 {
|
||||
return !isInternalConnector(name)
|
||||
}
|
||||
|
||||
for _, ext := range c.External {
|
||||
if strings.HasPrefix(ext, "desc:") {
|
||||
switch {
|
||||
case strings.HasPrefix(ext, "desc:"):
|
||||
desc := strings.TrimPrefix(ext, "desc:")
|
||||
if strings.Contains(description, desc) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
if name == ext {
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user