-
-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix monitor preferences #1241
base: master
Are you sure you want to change the base?
Fix monitor preferences #1241
Conversation
Now that we have proof, I dug even further and found a hardware serial number ID which I managed to get out of WMI, I have a commit on a branch with this integrated into This commit also updates the [
{
"id": 1804802517,
"name": "DISPLAY1",
"device": "DEL4310",
"device_id": "DEL4310-5&1a6c0954&0&UID209155",
"serial_number_id": "9SZGCP3",
"size": {
"left": 0,
"top": 0,
"right": 5120,
"bottom": 2160
}
}
] With what now looks to be a truly unique ID which persists across sessions and restarts (proof here on Discord?), the changes proposed in this PR should hopefully help stabilize monitor related madness once and for all 🤞 |
Previously, when caching a workspace config for a monitor it would simply store the `DefaultLayout` on `layout` even if the original workspace config had the `layout` as `None` which makes komorebi create a workspace with the `layout` as default `BSP` and the `tile` set at `false`. However this wasn't being taken into consideration, so floating workspaces would becoming tiling `BSP` workspaces after a monitor disconnect and reconnect. This commit fixes this by turning the `layout` to `None` when `tile` is `false`.
Store the `WorkspaceConfig` on the `Workspace` itself so that when we want to cache the workspace as `WorkspaceConfig` on the monitor cache it properly saves things like the workspace rules and the custom layout and custom layout rules.
This commit reworks the way the `postload` and the `reload` functions apply the monitor configs to the monitors. Previously it was looping through the monitor configs and applying them to the monitor with the index corresponding to the config's index. However this isn't correct, since the user might set the preferred indices for 3 monitors (like monitor A, B and C), with the preferred index set to 0 for A, 1 for B and 2 for C, but if only monitors A and C are connected then komorebi would apply config 0 to A and config 1 to C, which is wrong it should be 2 for C. This commit changes the way the configs are applied on those functions. Now it loops through the existing monitors (already in order), then checks if the monitor has a preferred config index, if it does it uses that one, if it doesn't then it uses the first monitor config that isn't a preferred index for some other monitor and that hasn't been used yet. For the situation above it means that it would still apply config 2 to monitor C. And in case there aren't any display_index_preferences set it will still apply the configs in order.
If we have display_index_preferences that set a specific config index for a specific display device, but that device isn't loaded yet, now we store that config with the corresponding `device_id` on the monitor cache so that when the display is connected it can load the correct config from the cache.
When a monitor was disconnected the containers from the removed monitor were being moved to the primary monitor. However they weren't restored so containers that were on an unfocused workspace of the removed monitor would have been cloak and were getting added to the main monitor still cloaked creating ghost tiles. This commit fixes that.
@LGUG2Z What should we do now in regards to the |
Let's keep the same config option but attempt to match against both serial_id_number and device_id (as a fallback) for the next few versions before eventually phasing out device_id |
c9190e1
to
7dc10a5
Compare
I've made the changes to allow using both Imagine a setup with 3 monitors from left to right monitors A, B and C. If you set your "display_index_preferences": {
"0": "serial_number_A",
"1": "serial_number_B",
"2": "serial_number_C"
} You expect each monitor to have the correct config from the map above even if one of them is not connected (this should be easy to fix, I hope...). Now the hard part is, imagine that monitor B is disconnected (or went to sleep like some monitors can do) do you expect all commands that take a monitor index to obey the map above, or should monitor C now have index 1? Same thing for all If the answer to all the questions above is that the indices shouldn't change and the commands should still work as expected and the rules should work as expected, then I fear my idea won't be enough and we'll have to change the monitors from a P.S. BTW my idea was to create a @LGUG2Z Please tell me which idea do you think is better or if you have a better one?! I'm happy to try pursuing any idea. Also I can't guarantee that any of these ideas (even the change from |
This commit makes use of both `serial_number_id` and `device_id` with the first taking priority on all monitor reconciliator code, monitor cache and on postload and reload. This should allow using the serial numbers on the `display_index_preferences` config, while keeping compatibility with the use of `device_id`. Although using `device_id` should be discourage since that value can change on restart while serial number doesn't appear to do so.
7dc10a5
to
b89228a
Compare
I think what is in this PR is good to merge once we get a few people to sanity test it I think we spoke last week on Discord about the idea of having users define possible monitor combinations, including specifying which combinations of monitors should be considered mutually exclusive. I think this idea is worth exploring more in the spirit of "make invalid states unrepresentable" This is definitely a more long-term project, but take a look at what I've roughly doodled out here with comments: {
// workspaces are declared independently of monitors
"workspaces": {
// the key here is the name
"primary_one": { "layout": "BSP" },
// the value here is the same as the Workspace struct
"primary_two": { "layout": "BSP" },
"vertical_one": { "layout": "Rows" },
"vertical_two": { "layout": "Rows" },
"laptop_one": { "layout": "BSP" },
"laptop_two": { "layout": "BSP" },
"work_one": { "layout": "BSP" },
"work_two": { "layout": "BSP" },
},
// locations encompass valid combinations of monitor serial ids
"locations": {
"work": {
"monitors": {
// workspaces are bound to monitors per-location
"s333-laptop": {
"workspaces": ["laptop_one", "laptop_two"],
},
// the key here is the serial_id
"s444-work-external": {
"workspaces": ["work_one", "work_two"],
},
},
// valid monitor combinations must have their index preferences declared
"combinations": [
{
"serials": ["s444-work-external", "s333-laptop"],
"index_preferences": [0, 1],
},
{
"serials": ["s444-work-external"],
"index_preferences": [0],
},
{
"serials": ["s333-laptop"],
"index_preferences": [0],
},
],
// explicit behaviours for what to do when a display is disconnected
"disconnect_behaviours": {
"s333-laptop": {
// not sure what the full range of actions here would be
"SendWorkspacesTo": "s444-work-external",
},
"s444-work-external": {
// maybe if the destination is also not available they can be stored
// in a cache indexed on ws name
"SendWorkspacesTo": "s333-laptop",
},
},
// explicit behaviours for what to do when a display is reconnected
"connect_behaviours": {
"s444-work-external": {
"RetrieveWorkspaces": ["work_one", "work_two"]
}
"s333-laptop": {
"RetrieveWorkspaces": ["laptop_one", "laptop_two"],
},
},
},
"home": {
"monitors": {
"s111-ultrawide": {
"workspaces": ["primary_one", "primary_two"],
},
"s222-vertical": {
"workspaces": ["vertical_one", "vertical_two"],
},
"s333-laptop": {
"workspaces": ["laptop_one", "laptop_two"],
},
},
"combinations": [
{
"serials": ["s111-ultrawide", "s222-vertical", "s333-laptop"],
"index_preferences": [0, 1, 2],
},
{
"serials": ["s111-ultrawide", "s333-laptop"],
"index_preferences": [0, 1],
},
{
"serials": ["s111-ultrawide", "s222-vertical"],
"index_preferences": [0, 1],
},
{
"serials": ["s111-ultrawide"],
"index_preferences": [0],
},
{
"serials": ["s333-laptop"],
"index_preferences": [0],
},
],
"disconnect_behaviours": {
"s111-ultrawide": "Pause",
"s222-vertical": {
"SendWorkspacesTo": "s111-ultrawide",
},
"s333-laptop": {
"SendWorkspacesTo": "s111-ultrawide",
},
},
"connect_behaviours": {
"s111-ultrawide": "Unpause",
"s222-vertical": {
"RetrieveWorkspaces": ["vertical_one", "vertical_two"],
},
"s333-laptop": {
"RetrieveWorkspaces": ["laptop_one", "laptop_two"],
},
},
},
},
} I think if people want to opt in to this kind of of advanced behaviour, komorebi should go all-in on requiring a fully declarative definition of what should happen in different scenarios; there is no way to satisfy what everyone's different definition of "it should just work" is, so instead we should make replicable configurations available both for users to be explicit about their expectations, and for developers to be able to validate and test. |
This is interesting, but I find it would be too much and too confusing for most users. As for this PR, currently it doesn't fix much. It simply changes the But I feel that most issues that people with multiple monitors are facing are actually related to the issues mentioned on my comment above where the indices of commands and rules get mixed up when some monitor goes to sleep. I guess we can look into those issues in another PR and keep this one just as "apply monitor config preferences correctly"... |
This commit makes sure that any workspace_rules that tried to move a window to a monitor that has been disconnected are removed. If the monitor is latter reconnected the workspace_rules should be added from the cached config.
This commit creates a new field on the `WindowManager` called `monitor_usr_idx_map` which contains a map of user intended index for monitors to their actual monitors' index. It will be rebuilt on `load_monitor_information` by taking into account the `display_index_preferences`.
@LGUG2Z So I've added a few things more with the last 3 commits:
|
This commit makes so a bar can be disabled when it's monitor is disconnected and re-enabled when said monitor reconnects. This commit also uses the new `monitor_usr_idx_map` to properly map the monitor index given by the users on config to the actual monitor index on the `WindowManager`, since in case some middle monitor gets disconnected the index of the monitors to the "right" of that one will be lowered by 1. This should allow for cases with monitor A, B and C, if monitor B disconnects, its bar will be disabled and monitor C will properly change its monitor index internally to 1 so it still gets the infos from monitor C (which now will have index 1 on the `WindowManager`).
dcc7dc6
to
82a4590
Compare
This PR reworks the way the
postload
and thereload
functions apply the monitor configs to the monitors. Previously it was looping through the monitor configs and applying them to the monitor with the index corresponding to the config's index.However this isn't correct, since the user might set the preferred indices for 3 monitors (like monitor A, B and C), with the preferred index set to 0 for A, 1 for B and 2 for C, but if only monitors A and C are connected then komorebi would apply config 0 to A and config 1 to C, which is wrong it should be 2 for C.
This PR changes the way the configs are applied on those functions.
Now it loops through the existing monitors (already in order), then checks if the monitor has a preferred config index, if it does it uses that one, if it doesn't then it uses the first monitor config that isn't a preferred index for some other monitor and that hasn't been used yet.
For the situation above it means that it would still apply config 2 to monitor C. And in case there aren't any display_index_preferences set it will still apply the configs in order.
It also changes the way the layout is stored from the current monitor, by making sure to set it to
None
if the workspace is not tiling. Previously any floating workspace would be restored from cache with a tiling BSP layout.Related to this discussion on Discord
However this entire code is based on the premise that the
device_id
is always the same for the same devices. However there have been comments on discord stating that this isn't true, however I've not been able to confirm this and the users have not given any proof of this happening (they might simply be confusing it since it's a weird string similar between monitors...)I think the changes from this PR should fix most issues that people have been having with multiple monitors (specially with 3 or more monitors). But it's probably better to not merge this until we can get some users to test it.