config: Make read_outputs failable
Previously we ignored when we had no output configuration **and** failed to apply the automatically created one. This leads to two problems: - If this happens on startup, we end up with no outputs being added to the shell and we quit. - If this happens later, we might end up in an inconsistent state, where the shell thinks we have an output, when it didn't light up for similar reasons. Thus `read_outputs` is failable and handling that very much depends on the where is was called from, because `read_outputs` doesn't know what configuration was active before. Thus make it failable and provide useful mitigations everywhere possible: - Try to enable just one output in case we fail on startup. - Don't enable any additional outputs, when we fail on hotplug. - Log the error like previously in any other case (and come up with more mitigations, once we understand these cases better).
This commit is contained in:
parent
cd1117080c
commit
b83e9f1d32
8 changed files with 232 additions and 91 deletions
|
|
@ -8,6 +8,7 @@ use crate::{
|
|||
output_configuration::OutputConfigurationState, workspace::WorkspaceUpdateGuard,
|
||||
},
|
||||
};
|
||||
use anyhow::Context;
|
||||
use cosmic_config::{ConfigGet, CosmicConfigEntry};
|
||||
use cosmic_settings_config::window_rules::ApplicationException;
|
||||
use cosmic_settings_config::{shortcuts, window_rules, Shortcuts};
|
||||
|
|
@ -386,7 +387,7 @@ impl Config {
|
|||
xdg_activation_state: &XdgActivationState,
|
||||
startup_done: Arc<AtomicBool>,
|
||||
clock: &Clock<Monotonic>,
|
||||
) {
|
||||
) -> anyhow::Result<()> {
|
||||
let outputs = output_state.outputs().collect::<Vec<_>>();
|
||||
let mut infos = outputs
|
||||
.iter()
|
||||
|
|
@ -471,24 +472,24 @@ impl Config {
|
|||
found_outputs.push((output.clone(), enabled));
|
||||
}
|
||||
|
||||
if let Err(err) = backend.apply_config_for_outputs(
|
||||
false,
|
||||
loop_handle,
|
||||
self.dynamic_conf.screen_filter(),
|
||||
shell.clone(),
|
||||
workspace_state,
|
||||
xdg_activation_state,
|
||||
startup_done,
|
||||
clock,
|
||||
) {
|
||||
error!(?err, "Failed to reset config.");
|
||||
} else {
|
||||
for (output, enabled) in found_outputs {
|
||||
if enabled == OutputState::Enabled {
|
||||
output_state.enable_head(&output);
|
||||
} else {
|
||||
output_state.disable_head(&output);
|
||||
}
|
||||
backend
|
||||
.apply_config_for_outputs(
|
||||
false,
|
||||
loop_handle,
|
||||
self.dynamic_conf.screen_filter(),
|
||||
shell.clone(),
|
||||
workspace_state,
|
||||
xdg_activation_state,
|
||||
startup_done,
|
||||
clock,
|
||||
)
|
||||
.context("Failed to reset config")?;
|
||||
|
||||
for (output, enabled) in found_outputs {
|
||||
if enabled == OutputState::Enabled {
|
||||
output_state.enable_head(&output);
|
||||
} else {
|
||||
output_state.disable_head(&output);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -529,37 +530,39 @@ impl Config {
|
|||
w += output.geometry().size.w as u32;
|
||||
}
|
||||
|
||||
if let Err(err) = backend.lock().apply_config_for_outputs(
|
||||
false,
|
||||
loop_handle,
|
||||
self.dynamic_conf.screen_filter(),
|
||||
shell.clone(),
|
||||
workspace_state,
|
||||
xdg_activation_state,
|
||||
startup_done,
|
||||
clock,
|
||||
) {
|
||||
warn!(?err, "Failed to set new config.",);
|
||||
} else {
|
||||
for output in outputs {
|
||||
if output
|
||||
.user_data()
|
||||
.get::<RefCell<OutputConfig>>()
|
||||
.unwrap()
|
||||
.borrow()
|
||||
.enabled
|
||||
== OutputState::Enabled
|
||||
{
|
||||
output_state.enable_head(&output);
|
||||
} else {
|
||||
output_state.disable_head(&output);
|
||||
}
|
||||
let mut backend = backend.lock();
|
||||
backend
|
||||
.apply_config_for_outputs(
|
||||
false,
|
||||
loop_handle,
|
||||
self.dynamic_conf.screen_filter(),
|
||||
shell.clone(),
|
||||
workspace_state,
|
||||
xdg_activation_state,
|
||||
startup_done.clone(),
|
||||
clock,
|
||||
)
|
||||
.context("Failed to set new config")?;
|
||||
|
||||
for output in outputs {
|
||||
if output
|
||||
.user_data()
|
||||
.get::<RefCell<OutputConfig>>()
|
||||
.unwrap()
|
||||
.borrow()
|
||||
.enabled
|
||||
== OutputState::Enabled
|
||||
{
|
||||
output_state.enable_head(&output);
|
||||
} else {
|
||||
output_state.disable_head(&output);
|
||||
}
|
||||
}
|
||||
|
||||
output_state.update();
|
||||
self.write_outputs(output_state.outputs());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn write_outputs(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue