-
-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathMonitorLayoutManager.vala
More file actions
107 lines (91 loc) · 4.4 KB
/
Copy pathMonitorLayoutManager.vala
File metadata and controls
107 lines (91 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
* SPDX-License-Identifier: GPL-2.0-or-later
* SPDX-FileCopyrightText: 2025 elementary, Inc. <https://elementary.io>
*
* Authored by: Leonardo Lemos <leonardolemos@live.com>
*/
public class Display.MonitorLayoutManager : GLib.Object {
private Settings settings;
private const string PREFERRED_MONITOR_LAYOUTS_KEY = "preferred-display-layouts";
public MonitorLayoutManager () {
Object ();
}
construct {
settings = new Settings ("io.elementary.settings.display");
}
public void arrange_monitors (Gee.LinkedList<VirtualMonitor> virtual_monitors) {
if (virtual_monitors.size == 1) {
// If there's only one monitor, no need to arrange
// Cloned monitors only have one virtual monitor so will return here
return;
}
var layout_key = get_layout_key (virtual_monitors);
// Layouts format are 'a{sa{sa{sv}}}'
var layouts = settings.get_value (PREFERRED_MONITOR_LAYOUTS_KEY);
Variant? monitors = null;
if (layouts != null) {
monitors = layouts.lookup_value (layout_key, VariantType.VARDICT);
foreach (var virtual_monitor in virtual_monitors) {
Variant? props = monitors.lookup_value (virtual_monitor.id, VariantType.VARDICT);
if (props != null) {
int32 x = 0, y = 0;
uint32 t = 0;
bool p = false, e = false;
if (props.lookup ("x", "i", out x) &&
props.lookup ("y", "i", out y) &&
props.lookup ("transform", "u", out t) &&
props.lookup ("primary", "b", out p) &&
props.lookup ("enabled", "b", out e)) {
virtual_monitor.x = x;
virtual_monitor.y = y;
virtual_monitor.transform = t;
virtual_monitor.primary = p;
virtual_monitor.is_active = e;
} else {
warning ("property setting missing for monitor %s", virtual_monitor.get_display_name ());
}
} else {
warning ("no property dictionary found for monitor.id %s", virtual_monitor.get_display_name ());
}
}
return;
} else {
warning ("layout key %s not found", layout_key);
}
// If no layout found, we save the current layout to use later
save_layout (virtual_monitors);
}
public void save_layout (Gee.LinkedList<VirtualMonitor> virtual_monitors) {
var save_key = get_layout_key (virtual_monitors);
var monitor_dict = new VariantDict ();
foreach (var monitor in virtual_monitors) {
var props_dict = new VariantDict ();
props_dict.insert_value ("x", new Variant.int32 (monitor.x));
props_dict.insert_value ("y", new Variant.int32 (monitor.y));
props_dict.insert_value ("transform", new Variant.uint32 (monitor.transform));
props_dict.insert_value ("primary", new Variant.boolean (monitor.primary));
props_dict.insert_value ("enabled", new Variant.boolean (monitor.is_active));
monitor_dict.insert_value (monitor.id, props_dict.end ());
}
// Add or update the layouts setting
var layouts = settings.get_value (PREFERRED_MONITOR_LAYOUTS_KEY);
var layouts_dict = new VariantDict (layouts);
layouts_dict.insert_value (save_key, monitor_dict.end ());
// Save to settings
//NOTE The variant yielded by VariantDict.end () always has type "a{sv}"
settings.set_value (PREFERRED_MONITOR_LAYOUTS_KEY, layouts_dict.end ());
}
private string get_layout_key (Gee.LinkedList<VirtualMonitor> virtual_monitors) {
// Generate a unique key based on the virtual monitors' monitors hashes
//NOTE The key depends on the order of the list which will change depending on whether monitors are
// active or not (and possibly on the order they were connected).
//TODO Consider whether a more controlled key is needed
var key = new StringBuilder ();
foreach (var virtual_monitor in virtual_monitors) {
foreach (var monitor in virtual_monitor.monitors) {
key.append (virtual_monitor.id);
}
}
return key.str;
}
}