-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding Display Page (without Night Mode), WIP on multiple screen conf…
…iguration
- Loading branch information
Showing
19 changed files
with
1,196 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
## GetCurrentState: | ||
@serial: configuration serial | ||
@monitors: available monitors | ||
@logical_monitors: current logical monitor configuration | ||
@properties: display configuration properties | ||
@monitors represent connected physical monitors | ||
* s connector: connector name (e.g. HDMI-1, DP-1, etc) | ||
* s vendor: vendor name | ||
* s product: product name | ||
* s serial: product serial | ||
* a(siiddada{sv}) modes: available modes | ||
* s id: mode ID | ||
* i width: width in physical pixels | ||
* i height: height in physical pixels | ||
* d refresh rate: refresh rate | ||
* d preferred scale: scale preferred as per calculations | ||
* ad supported scales: scales supported by this mode | ||
* a{sv} properties: optional properties, including: | ||
- "is-current" (b): the mode is currently active mode | ||
- "is-preferred" (b): the mode is the preferred mode | ||
* a{sv} properties: optional properties, including: | ||
- "width-mm" (i): physical width of monitor in millimeters | ||
- "height-mm" (i): physical height of monitor in millimeters | ||
- "is-underscanning" (b): whether underscanning is enabled | ||
(absence of this means underscanning | ||
not being supported) | ||
- "max-screen-size" (ii): the maximum size a screen may have | ||
(absence of this means unlimited screen | ||
size) | ||
- "is-builtin" (b): whether the monitor is built in, e.g. a | ||
laptop panel (absence of this means it is | ||
not built in) | ||
- "display-name" (s): a human readable display name of the monitor | ||
Possible mode flags: | ||
1 : preferred mode | ||
2 : current mode | ||
@logical_monitors represent current logical monitor configuration | ||
* i x: x position | ||
* i y: y position | ||
* d scale: scale | ||
* u transform: transform (see below) | ||
* b primary: true if this is the primary logical monitor | ||
* a(sss) monitors: monitors displaying this logical monitor | ||
* connector: name of the connector (e.g. DP-1, eDP-1 etc) | ||
* vendor: vendor name | ||
* product: product name | ||
* serial: product serial | ||
* a{sv} properties: possibly other properties | ||
Posisble transform values: | ||
0: normal | ||
1: 90° | ||
2: 180° | ||
3: 270° | ||
4: flipped | ||
5: 90° flipped | ||
6: 180° flipped | ||
7: 270° flipped | ||
@layout_mode current layout mode represents the way logical monitors | ||
are layed out on the screen. Possible modes include: | ||
1 : physical | ||
2 : logical | ||
With physical layout mode, each logical monitor has the same dimensions | ||
an the monitor modes of the associated monitors assigned to it, no | ||
matter what scale is in use. | ||
With logical mode, the dimension of a logical monitor is the dimension | ||
of the monitor mode, divided by the logical monitor scale. | ||
Possible @properties are: | ||
* "supports-mirroring" (b): FALSE if mirroring not supported; TRUE or not | ||
present if mirroring is supported. | ||
* "layout-mode" (u): Represents in what way logical monitors are laid | ||
out on the screen. The layout mode can be either | ||
of the ones listed below. Absence of this property | ||
means the layout mode cannot be changed, and that | ||
"logical" mode is assumed to be used. | ||
* 1 : logical - the dimension of a logical monitor is derived from | ||
the monitor modes associated with it, then scaled | ||
using the logical monitor scale. | ||
* 2 : physical - the dimension of a logical monitor is derived from | ||
the monitor modes associated with it. | ||
* "supports-changing-layout-mode" (b): True if the layout mode can be | ||
changed. Absence of this means the | ||
layout mode cannot be changed. | ||
* "global-scale-required" (b): True if all the logical monitors must | ||
always use the same scale. Absence of | ||
this means logical monitor scales can | ||
differ. | ||
|
||
## ApplyMonitorsConfig: | ||
@serial: configuration serial | ||
@method: configuration method | ||
@logical_monitors: monitors configuration | ||
@properties: properties | ||
@method represents the way the configuration should be handled. | ||
Possible methods: | ||
0: verify | ||
1: temporary | ||
2: persistent | ||
@logical_monitors consists of a list of logical monitor configurations. | ||
Each logical monitor configuration consists of: | ||
* i: layout x position | ||
* i: layout y position | ||
* d: scale | ||
* u: transform (see GetCurrentState) | ||
* b primary: true if this is the primary logical monitor | ||
* a(ssa{sv}): a list of monitors, each consisting of: | ||
* s: connector | ||
* s: monitor mode ID | ||
* a{sv}: monitor properties, including: | ||
- "enable_underscanning" (b): enable monitor underscanning; | ||
may only be set when underscanning | ||
is supported (see GetCurrentState). | ||
@properties may effect the global monitor configuration state. Possible | ||
properties are: | ||
* "layout-mode" (u): layout mode the passed configuration is in; may | ||
only be set when changing the layout mode is | ||
supported (see GetCurrentState). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import 'package:dbus/dbus.dart'; | ||
import 'package:settings/api/display/objects/dbus_displays_config.dart'; | ||
import 'package:settings/generated/dbus/display-config-remote-object.dart'; | ||
import 'package:settings/services/display_service.dart'; | ||
|
||
const displaysInterface = 'org.gnome.Mutter.DisplayConfig'; | ||
|
||
const displayPath = '/org/gnome/Mutter/DisplayConfig'; | ||
|
||
/// | ||
/// Methods: | ||
/// | ||
/// ApplyConfiguration (UInt32 serial, Boolean persistent, Array of [Struct of (UInt32, Int32, Int32, Int32, UInt32, Array of [UInt32], Dict of {String, Variant})] crtcs, Array of [Struct of (UInt32, Dict of {String, Variant})] outputs) ↦ () | ||
/// ApplyMonitorsConfig (UInt32 serial, UInt32 method, Array of [Struct of (Int32, Int32, Double, UInt32, Boolean, Array of [Struct of (String, String, Dict of {String, Variant})])] logical_monitors, Dict of {String, Variant} properties) ↦ () | ||
/// ChangeBacklight (UInt32 serial, UInt32 output, Int32 value) ↦ (Int32 new_value) | ||
/// GetCrtcGamma (UInt32 serial, UInt32 crtc) ↦ (Array of [UInt16] red, Array of [UInt16] green, Array of [UInt16] blue) | ||
/// GetCurrentState () ↦ (UInt32 serial, Array of [Struct of (Struct of (String, String, String, String), Array of [Struct of (String, Int32, Int32, Double, Double, Array of [Double], Dict of {String, Variant})], Dict of {String, Variant})] monitors, Array of [Struct of (Int32, Int32, Double, UInt32, Boolean, Array of [Struct of (String, String, String, String)], Dict of {String, Variant})] logical_monitors, Dict of {String, Variant} properties) | ||
/// GetResources () ↦ (UInt32 serial, Array of [Struct of (UInt32, Int64, Int32, Int32, Int32, Int32, Int32, UInt32, Array of [UInt32], Dict of {String, Variant})] crtcs, Array of [Struct of (UInt32, Int64, Int32, Array of [UInt32], String, Array of [UInt32], Array of [UInt32], Dict of {String, Variant})] outputs, Array of [Struct of (UInt32, Int64, UInt32, UInt32, Double, UInt32)] modes, Int32 max_screen_width, Int32 max_screen_height) | ||
/// SetCrtcGamma (UInt32 serial, UInt32 crtc, Array of [UInt16] red, Array of [UInt16] green, Array of [UInt16] blue) ↦ () | ||
/// SetOutputCTM (UInt32 serial, UInt32 output, Struct of (UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64) ctm) ↦ () | ||
/// | ||
/// Signals: | ||
/// | ||
/// MonitorsChanged | ||
class DisplayApi { | ||
DisplayApi() : _object = _createObject() { | ||
/// Listen to signal stream, when a change occur, we update our data | ||
_object.monitorsChanged | ||
.listen((OrgGnomeMutterDisplayConfigMonitorsChanged signal) { | ||
if (signal.name == 'MonitorsChanged') { | ||
getCurrent(); | ||
} | ||
}); | ||
} | ||
|
||
final OrgGnomeMutterDisplayConfig _object; | ||
|
||
Stream<DBusDisplaysConfig> get streamChanges => | ||
_object.monitorsChanged | ||
.asyncMap((event) async => getCurrent()); | ||
|
||
static OrgGnomeMutterDisplayConfig _createObject() => | ||
OrgGnomeMutterDisplayConfig( | ||
DBusClient.session(), | ||
displaysInterface, | ||
DBusObjectPath(displayPath), | ||
); | ||
|
||
Future<DBusDisplaysConfig> getCurrent() async { | ||
List<DBusValue>? state = await _object.callGetCurrentState(); | ||
|
||
List<dynamic> list = state.map((e) => _toNative(e)).toList(); | ||
|
||
return DBusDisplaysConfig(list); | ||
} | ||
|
||
Future<void> apply(int serial, ConfigurationMethod configurationMethod, | ||
List<DBusStruct> logicalParameterValues) => | ||
_object.callApplyMonitorsConfig( | ||
serial, | ||
configurationMethod.index, | ||
logicalParameterValues, | ||
{}, | ||
); | ||
|
||
dynamic _toNative(dynamic value) { | ||
dynamic output; | ||
|
||
if (value is Map) { | ||
output = | ||
value.map((key, value) => MapEntry(_toNative(key), _toNative(value))); | ||
} else if (value is Iterable) { | ||
output = value.map((e) => _toNative(e)).toList(); | ||
} else if (value is DBusArray) { | ||
output = value.toNative().map((e) => _toNative(e)).toList(); | ||
} else if (value is DBusValue) { | ||
output = value.toNative(); | ||
} else { | ||
return value; | ||
} | ||
|
||
return output; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
class DBusDisplaysConfig { | ||
DBusDisplaysConfig(List<dynamic> list) | ||
: serial = list[0], | ||
_monitors = list[1], | ||
_logicalMonitors = list[2]; | ||
|
||
//_properties = list[3]; | ||
|
||
/// @serial: configuration serial | ||
final int serial; | ||
|
||
/// @monitors: available monitors | ||
final List<dynamic> _monitors; | ||
|
||
/// @logical_monitors: current logical monitor configuration | ||
final List<dynamic> _logicalMonitors; | ||
|
||
/// @properties: display configuration properties | ||
//final Map<dynamic, dynamic> _properties; | ||
|
||
/// * s connector: connector name (e.g. HDMI-1, DP-1, etc) | ||
/// * s vendor: vendor name | ||
/// * s product: product name | ||
/// * s serial: product serial | ||
_Identity identity(index) => _Identity(_monitors[index][0]); | ||
|
||
/// * a(siiddada{sv}) modes: available modes | ||
List<_Option> availableOptions(index) => | ||
(_monitors[index][1] as List<dynamic>).map((e) => _Option(e)).toList(); | ||
|
||
_Option currentOption(index) => | ||
availableOptions(index).where((element) => element.isCurrent).first; | ||
|
||
///@logical_monitors represent current logical monitor configuration | ||
/// * i x: x position | ||
/// * i y: y position | ||
/// * d scale: scale | ||
/// * u transform: transform (see below) | ||
/// * b primary: true if this is the primary logical monitor | ||
/// * a(sss) monitors: monitors displaying this logical monitor | ||
/// * connector: name of the connector (e.g. DP-1, eDP-1 etc) | ||
/// * vendor: vendor name | ||
/// * product: product name | ||
/// * serial: product serial | ||
/// * a{sv} properties: possibly other properties | ||
/// @layout_mode current layout mode represents the way logical monitors | ||
/// are layed out on the screen. Possible modes include: | ||
/// 1 : physical | ||
/// 2 : logical | ||
/// With physical layout mode, each logical monitor has the same dimensions | ||
/// an the monitor modes of the associated monitors assigned to it, no | ||
/// matter what scale is in use. | ||
/// With logical mode, the dimension of a logical monitor is the dimension | ||
/// of the monitor mode, divided by the logical monitor scale. | ||
/// Possible @properties are: | ||
/// * "supports-mirroring" (b): FALSE if mirroring not supported; TRUE or not | ||
/// present if mirroring is supported. | ||
/// * "layout-mode" (u): Represents in what way logical monitors are laid | ||
/// out on the screen. The layout mode can be either | ||
/// of the ones listed below. Absence of this property | ||
/// means the layout mode cannot be changed, and that | ||
/// "logical" mode is assumed to be used. | ||
/// * 1 : logical - the dimension of a logical monitor is derived from | ||
/// the monitor modes associated with it, then scaled | ||
/// using the logical monitor scale. | ||
/// * 2 : physical - the dimension of a logical monitor is derived from | ||
/// the monitor modes associated with it. | ||
/// * "supports-changing-layout-mode" (b): True if the layout mode can be | ||
/// changed. Absence of this means the | ||
/// layout mode cannot be changed. | ||
/// * "global-scale-required" (b): True if all the logical monitors must | ||
/// always use the same scale. Absence of | ||
/// this means logical monitor scales can | ||
/// differ. | ||
/// | ||
_LogicalConfiguration currentLogicalConfiguration(index) => | ||
_LogicalConfiguration(_logicalMonitors[index]); | ||
|
||
/// * a{sv} properties: optional properties, including: | ||
/// - "width-mm" (i): physical width of monitor in millimeters | ||
/// - "height-mm" (i): physical height of monitor in millimeters | ||
/// - "is-underscanning" (b): whether underscanning is enabled | ||
/// (absence of this means underscanning | ||
/// not being supported) | ||
/// - "max-screen-size" (ii): the maximum size a screen may have | ||
/// (absence of this means unlimited screen | ||
/// size) | ||
/// - "is-builtin" (b): whether the monitor is built in, e.g. a | ||
/// laptop panel (absence of this means it is | ||
/// not built in) | ||
/// - "display-name" (s): a human readable display name of the monitor | ||
/// Possible mode flags: | ||
/// 1 : preferred mode | ||
/// 2 : current mode | ||
String displayName(index) => _monitors[index][2]['display-name'] ?? ''; | ||
|
||
bool isBuiltin(index) => _monitors[index][2]['is-builtin'] ?? false; | ||
|
||
int get monitorsLength => _monitors.length; | ||
} | ||
|
||
class _Identity { | ||
_Identity(List<dynamic> monitors) | ||
: connector = monitors[0], | ||
vendor = monitors[1], | ||
product = monitors[2], | ||
serial = monitors[3]; | ||
|
||
final String connector; | ||
final String vendor; | ||
final String product; | ||
final String serial; | ||
} | ||
|
||
/// * a(siiddada{sv}) modes: available modes | ||
/// * s id: mode ID | ||
/// * i width: width in physical pixels | ||
/// * i height: height in physical pixels | ||
/// * d refresh rate: refresh rate | ||
/// * d preferred scale: scale preferred as per calculations | ||
/// * ad supported scales: scales supported by this mode | ||
/// * a{sv} properties: optional properties, including: | ||
/// - "is-current" (b): the mode is currently active mode | ||
/// - "is-preferred" (b): the mode is the preferred mode | ||
/// * a{sv} properties: optional properties, including: | ||
/// - "width-mm" (i): physical width of monitor in millimeters | ||
/// - "height-mm" (i): physical height of monitor in millimeters | ||
/// - "is-underscanning" (b): whether underscanning is enabled | ||
class _Option { | ||
_Option(List<dynamic> monitor) | ||
: modeId = monitor[0], | ||
x = monitor[1], | ||
y = monitor[2], | ||
refreshRate = monitor[3], | ||
scale = monitor[4], | ||
availableScales = (monitor[5] as List<dynamic>) | ||
.map((e) => double.parse(e.toString())) | ||
.toList(), | ||
isCurrent = monitor[6]['is-current'] == true, | ||
isPreferred = monitor[6]['is-preferred'] == true; | ||
|
||
final String modeId; | ||
final int x; | ||
final int y; | ||
final double refreshRate; | ||
final double scale; | ||
final List<double> availableScales; | ||
final bool isCurrent; | ||
final bool isPreferred; | ||
} | ||
|
||
class _LogicalConfiguration { | ||
_LogicalConfiguration(List<dynamic> logicalMonitor) | ||
: offsetX = logicalMonitor[0], | ||
offsetY = logicalMonitor[1], | ||
scale = logicalMonitor[2], | ||
orientation = logicalMonitor[3], | ||
primary = logicalMonitor[4]; | ||
|
||
final int offsetX; | ||
final int offsetY; | ||
final double scale; | ||
final int orientation; | ||
final bool primary; | ||
|
||
} |
Oops, something went wrong.