diff --git a/display1/exported_methods_auto.go b/display1/exported_methods_auto.go index 37bcaf6d7..997a93c9f 100644 --- a/display1/exported_methods_auto.go +++ b/display1/exported_methods_auto.go @@ -58,6 +58,11 @@ func (v *Manager) GetExportedMethods() dbusutil.ExportedMethods { Fn: v.GetRealDisplayMode, OutArgs: []string{"outArg0"}, }, + { + Name: "ListEffectiveOutputNames", + Fn: v.ListEffectiveOutputNames, + OutArgs: []string{"outArg0"}, + }, { Name: "ListOutputNames", Fn: v.ListOutputNames, diff --git a/display1/manager.go b/display1/manager.go index 37929cc85..b3c6c87b7 100644 --- a/display1/manager.go +++ b/display1/manager.go @@ -228,7 +228,6 @@ type Manager struct { HasChanged bool DisplayMode byte ConcatScreenEnabled bool - ConcatScreenName string // dbusutil-gen: equal=nil Brightness map[string]float64 CanSetBrightnessMap map[string]bool @@ -2369,7 +2368,7 @@ func (m *Manager) applyConcatScreen() error { } m.PropsMu.Lock() - m.setConcatScreenEnabled(true, concatScreenName) + m.setConcatScreenEnabled(true) m.PropsMu.Unlock() return nil } @@ -2385,17 +2384,15 @@ func (m *Manager) removeConcatScreen() error { } m.PropsMu.Lock() - m.setConcatScreenEnabled(false, "") + m.setConcatScreenEnabled(false) m.PropsMu.Unlock() return nil } -func (m *Manager) setConcatScreenEnabled(enabled bool, name string) (changed bool) { +func (m *Manager) setConcatScreenEnabled(enabled bool) (changed bool) { if m.ConcatScreenEnabled != enabled { m.ConcatScreenEnabled = enabled - m.ConcatScreenName = name _ = m.service.EmitPropertyChanged(m, "ConcatScreenEnabled", enabled) - _ = m.service.EmitPropertyChanged(m, "ConcatScreenName", name) return true } return false @@ -2567,6 +2564,36 @@ func (m *Manager) getConnectedMonitors() Monitors { return getConnectedMonitors(m.monitorMap) } +func (m *Manager) getEffectiveOutputNames() ([]string, error) { + if _useWayland { + return nil, errors.New("not supported on wayland") + } + + if m.xConn == nil { + return nil, errors.New("x connection not available") + } + + rootWindow := m.xConn.GetDefaultScreen().Root + cookie := randr.GetMonitors(m.xConn, rootWindow, true) + reply, err := cookie.Reply(m.xConn) + if err != nil { + return nil, fmt.Errorf("GetMonitors failed: %w", err) + } + var names []string + for i := range reply.Monitors { + atom := reply.Monitors[i].Name + if atom == 0 { + continue + } + name, err := m.xConn.GetAtomName(atom) + if err != nil || name == "" { + continue + } + names = append(names, name) + } + return names, nil +} + func (m *Manager) cloneMonitorMap() map[uint32]*Monitor { m.monitorMapMu.Lock() defer m.monitorMapMu.Unlock() diff --git a/display1/manager_ifc.go b/display1/manager_ifc.go index cebe78e5a..b2b9075a6 100644 --- a/display1/manager_ifc.go +++ b/display1/manager_ifc.go @@ -155,6 +155,22 @@ func (m *Manager) ListOutputNames() ([]string, *dbus.Error) { return names, nil } +// ListEffectiveOutputNames 返回当前所有有效显示器名 +// X11 下使用 randr.GetMonitors 返回物理 + 虚拟屏 +// Wayland 下复用 ListOutputNames 返回物理屏, +func (m *Manager) ListEffectiveOutputNames() ([]string, *dbus.Error) { + logger.Debug("dbus call ListEffectiveOutputNames") + if _useWayland { + return m.ListOutputNames() + } + + names, err := m.getEffectiveOutputNames() + if err != nil { + return nil, dbusutil.ToError(err) + } + return names, nil +} + func (m *Manager) ListOutputsCommonModes() ([]ModeInfo, *dbus.Error) { logger.Debug("dbus call ListOutputsCommonModes") monitors := m.getConnectedMonitors()