seat: Workaround old active outputs on hotplug
This commit is contained in:
parent
9c41c80345
commit
b2686424ea
9 changed files with 69 additions and 14 deletions
|
|
@ -33,6 +33,7 @@ use smithay::{
|
||||||
udev::{all_gpus, primary_gpu, UdevBackend, UdevEvent},
|
udev::{all_gpus, primary_gpu, UdevBackend, UdevEvent},
|
||||||
},
|
},
|
||||||
desktop::utils::OutputPresentationFeedback,
|
desktop::utils::OutputPresentationFeedback,
|
||||||
|
input::Seat,
|
||||||
output::{Mode as OutputMode, Output, PhysicalProperties, Subpixel},
|
output::{Mode as OutputMode, Output, PhysicalProperties, Subpixel},
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{
|
calloop::{
|
||||||
|
|
@ -255,10 +256,12 @@ pub fn init_backend(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let seats = data.state.common.seats().cloned().collect::<Vec<_>>();
|
||||||
data.state.common.config.read_outputs(
|
data.state.common.config.read_outputs(
|
||||||
&mut data.state.common.output_configuration_state,
|
&mut data.state.common.output_configuration_state,
|
||||||
&mut data.state.backend,
|
&mut data.state.backend,
|
||||||
&mut data.state.common.shell,
|
&mut data.state.common.shell,
|
||||||
|
seats.into_iter(),
|
||||||
&data.state.common.event_loop_handle,
|
&data.state.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
for surface in data
|
for surface in data
|
||||||
|
|
@ -534,10 +537,12 @@ impl State {
|
||||||
self.common
|
self.common
|
||||||
.output_configuration_state
|
.output_configuration_state
|
||||||
.add_heads(wl_outputs.iter());
|
.add_heads(wl_outputs.iter());
|
||||||
|
let seats = self.common.seats().cloned().collect::<Vec<_>>();
|
||||||
self.common.config.read_outputs(
|
self.common.config.read_outputs(
|
||||||
&mut self.common.output_configuration_state,
|
&mut self.common.output_configuration_state,
|
||||||
&mut self.backend,
|
&mut self.backend,
|
||||||
&mut self.common.shell,
|
&mut self.common.shell,
|
||||||
|
seats.into_iter(),
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -600,13 +605,17 @@ impl State {
|
||||||
self.common
|
self.common
|
||||||
.output_configuration_state
|
.output_configuration_state
|
||||||
.add_heads(outputs_added.iter());
|
.add_heads(outputs_added.iter());
|
||||||
|
let seats = self.common.seats().cloned().collect::<Vec<_>>();
|
||||||
for output in outputs_removed {
|
for output in outputs_removed {
|
||||||
self.common.shell.remove_output(&output);
|
self.common
|
||||||
|
.shell
|
||||||
|
.remove_output(&output, seats.iter().cloned());
|
||||||
}
|
}
|
||||||
self.common.config.read_outputs(
|
self.common.config.read_outputs(
|
||||||
&mut self.common.output_configuration_state,
|
&mut self.common.output_configuration_state,
|
||||||
&mut self.backend,
|
&mut self.backend,
|
||||||
&mut self.common.shell,
|
&mut self.common.shell,
|
||||||
|
seats.into_iter(),
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -638,14 +647,18 @@ impl State {
|
||||||
.output_configuration_state
|
.output_configuration_state
|
||||||
.remove_heads(outputs_removed.iter());
|
.remove_heads(outputs_removed.iter());
|
||||||
|
|
||||||
|
let seats = self.common.seats().cloned().collect::<Vec<_>>();
|
||||||
if self.backend.kms().session.is_active() {
|
if self.backend.kms().session.is_active() {
|
||||||
for output in outputs_removed {
|
for output in outputs_removed {
|
||||||
self.common.shell.remove_output(&output);
|
self.common
|
||||||
|
.shell
|
||||||
|
.remove_output(&output, seats.iter().cloned());
|
||||||
}
|
}
|
||||||
self.common.config.read_outputs(
|
self.common.config.read_outputs(
|
||||||
&mut self.common.output_configuration_state,
|
&mut self.common.output_configuration_state,
|
||||||
&mut self.backend,
|
&mut self.backend,
|
||||||
&mut self.common.shell,
|
&mut self.common.shell,
|
||||||
|
seats.into_iter(),
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -880,6 +893,7 @@ impl KmsState {
|
||||||
pub fn apply_config_for_output(
|
pub fn apply_config_for_output(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
|
seats: impl Iterator<Item = Seat<State>>,
|
||||||
shell: &mut Shell,
|
shell: &mut Shell,
|
||||||
test_only: bool,
|
test_only: bool,
|
||||||
loop_handle: &LoopHandle<'_, Data>,
|
loop_handle: &LoopHandle<'_, Data>,
|
||||||
|
|
@ -902,7 +916,7 @@ impl KmsState {
|
||||||
|
|
||||||
if !output_config.enabled {
|
if !output_config.enabled {
|
||||||
if !test_only {
|
if !test_only {
|
||||||
shell.remove_output(output);
|
shell.remove_output(output, seats);
|
||||||
if surface.surface.take().is_some() {
|
if surface.surface.take().is_some() {
|
||||||
// just drop it
|
// just drop it
|
||||||
surface.pending = false;
|
surface.pending = false;
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,11 @@ pub fn init_backend(
|
||||||
}
|
}
|
||||||
Err(winit::WinitError::WindowClosed) => {
|
Err(winit::WinitError::WindowClosed) => {
|
||||||
let output = data.state.backend.winit().output.clone();
|
let output = data.state.backend.winit().output.clone();
|
||||||
data.state.common.shell.remove_output(&output);
|
let seats = data.state.common.seats().cloned().collect::<Vec<_>>();
|
||||||
|
data.state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.remove_output(&output, seats.into_iter());
|
||||||
if let Some(token) = token.take() {
|
if let Some(token) = token.take() {
|
||||||
event_loop_handle.remove(token);
|
event_loop_handle.remove(token);
|
||||||
}
|
}
|
||||||
|
|
@ -237,10 +241,12 @@ pub fn init_backend(
|
||||||
.output_configuration_state
|
.output_configuration_state
|
||||||
.add_heads(std::iter::once(&output));
|
.add_heads(std::iter::once(&output));
|
||||||
state.common.shell.add_output(&output);
|
state.common.shell.add_output(&output);
|
||||||
|
let seats = state.common.seats().cloned().collect::<Vec<_>>();
|
||||||
state.common.config.read_outputs(
|
state.common.config.read_outputs(
|
||||||
&mut state.common.output_configuration_state,
|
&mut state.common.output_configuration_state,
|
||||||
&mut state.backend,
|
&mut state.backend,
|
||||||
&mut state.common.shell,
|
&mut state.common.shell,
|
||||||
|
seats.iter().cloned(),
|
||||||
&state.common.event_loop_handle,
|
&state.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -296,16 +296,18 @@ pub fn init_backend(
|
||||||
.output_configuration_state
|
.output_configuration_state
|
||||||
.add_heads(std::iter::once(&output));
|
.add_heads(std::iter::once(&output));
|
||||||
state.common.shell.add_output(&output);
|
state.common.shell.add_output(&output);
|
||||||
|
let seats = state.common.seats().cloned().collect::<Vec<_>>();
|
||||||
state.common.config.read_outputs(
|
state.common.config.read_outputs(
|
||||||
&mut state.common.output_configuration_state,
|
&mut state.common.output_configuration_state,
|
||||||
&mut state.backend,
|
&mut state.backend,
|
||||||
&mut state.common.shell,
|
&mut state.common.shell,
|
||||||
|
seats.iter().cloned(),
|
||||||
&state.common.event_loop_handle,
|
&state.common.event_loop_handle,
|
||||||
);
|
);
|
||||||
|
|
||||||
event_loop
|
event_loop
|
||||||
.handle()
|
.handle()
|
||||||
.insert_source(backend, |event, _, data| match event {
|
.insert_source(backend, move |event, _, data| match event {
|
||||||
X11Event::CloseRequested { window_id } => {
|
X11Event::CloseRequested { window_id } => {
|
||||||
// TODO: drain_filter
|
// TODO: drain_filter
|
||||||
let mut outputs_removed = Vec::new();
|
let mut outputs_removed = Vec::new();
|
||||||
|
|
@ -326,7 +328,10 @@ pub fn init_backend(
|
||||||
.surfaces
|
.surfaces
|
||||||
.retain(|s| s.window.id() != window_id);
|
.retain(|s| s.window.id() != window_id);
|
||||||
for output in outputs_removed.into_iter() {
|
for output in outputs_removed.into_iter() {
|
||||||
data.state.common.shell.remove_output(&output);
|
data.state
|
||||||
|
.common
|
||||||
|
.shell
|
||||||
|
.remove_output(&output, seats.iter().cloned());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
X11Event::Resized {
|
X11Event::Resized {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use crate::{
|
||||||
wayland::protocols::output_configuration::OutputConfigurationState,
|
wayland::protocols::output_configuration::OutputConfigurationState,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use smithay::input::Seat;
|
||||||
pub use smithay::{
|
pub use smithay::{
|
||||||
backend::input::KeyState,
|
backend::input::KeyState,
|
||||||
input::keyboard::{keysyms as KeySyms, Keysym, ModifiersState},
|
input::keyboard::{keysyms as KeySyms, Keysym, ModifiersState},
|
||||||
|
|
@ -282,8 +283,10 @@ impl Config {
|
||||||
output_state: &mut OutputConfigurationState<State>,
|
output_state: &mut OutputConfigurationState<State>,
|
||||||
backend: &mut BackendData,
|
backend: &mut BackendData,
|
||||||
shell: &mut Shell,
|
shell: &mut Shell,
|
||||||
|
seats: impl Iterator<Item = Seat<State>>,
|
||||||
loop_handle: &LoopHandle<'_, Data>,
|
loop_handle: &LoopHandle<'_, Data>,
|
||||||
) {
|
) {
|
||||||
|
let seats = seats.collect::<Vec<_>>();
|
||||||
let outputs = output_state.outputs().collect::<Vec<_>>();
|
let outputs = output_state.outputs().collect::<Vec<_>>();
|
||||||
let mut infos = outputs
|
let mut infos = outputs
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -314,9 +317,13 @@ impl Config {
|
||||||
.get::<RefCell<OutputConfig>>()
|
.get::<RefCell<OutputConfig>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.borrow_mut() = output_config;
|
.borrow_mut() = output_config;
|
||||||
if let Err(err) =
|
if let Err(err) = backend.apply_config_for_output(
|
||||||
backend.apply_config_for_output(&output, false, shell, loop_handle)
|
&output,
|
||||||
{
|
false,
|
||||||
|
shell,
|
||||||
|
seats.iter().cloned(),
|
||||||
|
loop_handle,
|
||||||
|
) {
|
||||||
slog_scope::warn!(
|
slog_scope::warn!(
|
||||||
"Failed to set new config for output {}: {}",
|
"Failed to set new config for output {}: {}",
|
||||||
output.name(),
|
output.name(),
|
||||||
|
|
@ -345,9 +352,13 @@ impl Config {
|
||||||
.get::<RefCell<OutputConfig>>()
|
.get::<RefCell<OutputConfig>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.borrow_mut() = output_config;
|
.borrow_mut() = output_config;
|
||||||
if let Err(err) =
|
if let Err(err) = backend.apply_config_for_output(
|
||||||
backend.apply_config_for_output(&output, false, shell, loop_handle)
|
&output,
|
||||||
{
|
false,
|
||||||
|
shell,
|
||||||
|
seats.iter().cloned(),
|
||||||
|
loop_handle,
|
||||||
|
) {
|
||||||
slog_scope::error!(
|
slog_scope::error!(
|
||||||
"Failed to reset config for output {}: {}",
|
"Failed to reset config for output {}: {}",
|
||||||
output.name(),
|
output.name(),
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,10 @@ impl Common {
|
||||||
let seats = state.common.seats().cloned().collect::<Vec<_>>();
|
let seats = state.common.seats().cloned().collect::<Vec<_>>();
|
||||||
for seat in seats {
|
for seat in seats {
|
||||||
let output = seat.active_output();
|
let output = seat.active_output();
|
||||||
|
if !state.common.shell.outputs.contains(&output) {
|
||||||
|
seat.set_active_output(&state.common.shell.outputs[0]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let last_known_focus = ActiveFocus::get(&seat);
|
let last_known_focus = ActiveFocus::get(&seat);
|
||||||
|
|
||||||
if let Some(target) = last_known_focus {
|
if let Some(target) = last_known_focus {
|
||||||
|
|
|
||||||
|
|
@ -448,7 +448,15 @@ impl Shell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_output(&mut self, output: &Output) {
|
pub fn remove_output(&mut self, output: &Output, seats: impl Iterator<Item = Seat<State>>) {
|
||||||
|
if let Some(first_output) = self.outputs.get(0) {
|
||||||
|
for seat in seats {
|
||||||
|
if &seat.active_output() == output {
|
||||||
|
seat.set_active_output(first_output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !self.outputs.contains(output) {
|
if !self.outputs.contains(output) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,11 +141,12 @@ impl BackendData {
|
||||||
output: &Output,
|
output: &Output,
|
||||||
test_only: bool,
|
test_only: bool,
|
||||||
shell: &mut Shell,
|
shell: &mut Shell,
|
||||||
|
seats: impl Iterator<Item = Seat<State>>,
|
||||||
loop_handle: &LoopHandle<'_, Data>,
|
loop_handle: &LoopHandle<'_, Data>,
|
||||||
) -> Result<(), anyhow::Error> {
|
) -> Result<(), anyhow::Error> {
|
||||||
let result = match self {
|
let result = match self {
|
||||||
BackendData::Kms(ref mut state) => {
|
BackendData::Kms(ref mut state) => {
|
||||||
state.apply_config_for_output(output, shell, test_only, loop_handle)
|
state.apply_config_for_output(output, seats, shell, test_only, loop_handle)
|
||||||
}
|
}
|
||||||
BackendData::Winit(ref mut state) => state.apply_config_for_output(output, test_only),
|
BackendData::Winit(ref mut state) => state.apply_config_for_output(output, test_only),
|
||||||
BackendData::X11(ref mut state) => state.apply_config_for_output(output, test_only),
|
BackendData::X11(ref mut state) => state.apply_config_for_output(output, test_only),
|
||||||
|
|
|
||||||
|
|
@ -81,10 +81,12 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let seats = self.common.seats().cloned().collect::<Vec<_>>();
|
||||||
if let Err(err) = self.backend.apply_config_for_output(
|
if let Err(err) = self.backend.apply_config_for_output(
|
||||||
output,
|
output,
|
||||||
test_only,
|
test_only,
|
||||||
&mut self.common.shell,
|
&mut self.common.shell,
|
||||||
|
seats.iter().cloned(),
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
) {
|
) {
|
||||||
slog_scope::warn!(
|
slog_scope::warn!(
|
||||||
|
|
@ -106,6 +108,7 @@ impl State {
|
||||||
output,
|
output,
|
||||||
false,
|
false,
|
||||||
&mut self.common.shell,
|
&mut self.common.shell,
|
||||||
|
seats.iter().cloned(),
|
||||||
&self.common.event_loop_handle,
|
&self.common.event_loop_handle,
|
||||||
) {
|
) {
|
||||||
slog_scope::error!(
|
slog_scope::error!(
|
||||||
|
|
|
||||||
|
|
@ -1018,6 +1018,9 @@ impl State {
|
||||||
if !session.alive() {
|
if !session.alive() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if !data.state.common.shell.outputs.contains(&output) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
match render_workspace_to_buffer(
|
match render_workspace_to_buffer(
|
||||||
&mut data.state,
|
&mut data.state,
|
||||||
&session,
|
&session,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue