xwm: Don't do multiple

This commit is contained in:
Victoria Brekenfeld 2023-03-07 20:28:41 +01:00
parent 7caae686fe
commit 659933b039
14 changed files with 114 additions and 90 deletions

View file

@ -331,7 +331,6 @@ pub fn init_backend(
// Create relative pointer global
RelativePointerManagerState::new::<State>(&dh);
// TODO: Do multiple Xwaylands for better multigpu
state.launch_xwayland(Some(primary));
for (dev, path) in udev_dispatcher.as_source_ref().device_list() {

View file

@ -298,7 +298,7 @@ where
renderer,
output,
&state.shell.override_redirect_windows,
state.xwayland_state.values_mut(),
state.xwayland_state.as_mut(),
(!move_active && active_output).then_some(&last_active_seat),
exclude_workspace_overview,
)

View file

@ -11,6 +11,7 @@ use crate::{
use anyhow::{anyhow, Context, Result};
use smithay::{
backend::{
egl::EGLDevice,
renderer::{
damage::DamageTrackedRenderer, gles2::Gles2Renderbuffer, glow::GlowRenderer, ImportDma,
ImportEgl,
@ -25,6 +26,7 @@ use smithay::{
wayland_server::DisplayHandle,
},
utils::Transform,
wayland::dmabuf::DmabufFeedbackBuilder,
};
use std::cell::RefCell;
use tracing::{error, info, warn};
@ -257,7 +259,6 @@ pub fn init_backend(
seats.iter().cloned(),
&state.common.event_loop_handle,
);
state.launch_xwayland(None);
Ok(())
@ -269,21 +270,56 @@ fn init_egl_client_side(
renderer: &mut WinitGraphicsBackend<GlowRenderer>,
) -> Result<()> {
let bind_result = renderer.renderer().bind_wl_display(dh);
match bind_result {
Ok(_) => {
let render_node = EGLDevice::device_for_display(renderer.renderer().egl_context().display())
.and_then(|device| device.try_get_render_node());
let dmabuf_formats = renderer
.renderer()
.dmabuf_formats()
.cloned()
.collect::<Vec<_>>();
let dmabuf_default_feedback = match render_node {
Ok(Some(node)) => {
let dmabuf_default_feedback =
DmabufFeedbackBuilder::new(node.dev_id(), dmabuf_formats.clone())
.build()
.unwrap();
Some(dmabuf_default_feedback)
}
Ok(None) => {
warn!("Failed to query render node, dmabuf protocol will only advertise v3");
None
}
Err(err) => {
warn!(
?err,
"Failed to egl device for display, dmabuf protocol will only advertise v3"
);
None
}
};
match dmabuf_default_feedback {
Some(feedback) => {
state
.common
.dmabuf_state
.create_global_with_default_feedback::<State>(dh, &feedback);
info!("EGL hardware-acceleration enabled.");
let dmabuf_formats = renderer
.renderer()
.dmabuf_formats()
.cloned()
.collect::<Vec<_>>();
}
None if bind_result.is_ok() => {
state
.common
.dmabuf_state
.create_global::<State>(dh, dmabuf_formats);
info!("EGL hardware-acceleration enabled.");
}
Err(err) => warn!(?err, "Unable to initialize bind display to EGL."),
};
None => {
let err = bind_result.unwrap_err();
warn!(?err, "Unable to initialize bind display to EGL.")
}
}
Ok(())
}

View file

@ -35,6 +35,7 @@ use smithay::{
wayland_server::DisplayHandle,
},
utils::{DeviceFd, Transform},
wayland::dmabuf::DmabufFeedbackBuilder,
};
use std::{cell::RefCell, os::unix::io::OwnedFd};
use tracing::{debug, error, info, warn};
@ -351,7 +352,7 @@ pub fn init_backend(
unsafe { GlowRenderer::new(context) }.with_context(|| "Failed to initialize renderer")?;
init_shaders(&mut renderer).expect("Failed to initialize renderer");
init_egl_client_side(dh, state, &mut renderer)?;
init_egl_client_side(dh, state, &drm_node, &mut renderer)?;
state.backend = BackendData::X11(X11State {
handle,
@ -381,7 +382,6 @@ pub fn init_backend(
seats.iter().cloned(),
&state.common.event_loop_handle,
);
state.launch_xwayland(None);
event_loop
@ -475,22 +475,32 @@ pub fn init_backend(
Ok(())
}
fn init_egl_client_side<R>(dh: &DisplayHandle, state: &mut State, renderer: &mut R) -> Result<()>
fn init_egl_client_side<R>(
dh: &DisplayHandle,
state: &mut State,
render_node: &DrmNode,
renderer: &mut R,
) -> Result<()>
where
R: ImportEgl + ImportDma,
{
let bind_result = renderer.bind_wl_display(dh);
match bind_result {
Ok(_) => {
info!("EGL hardware-acceleration enabled.");
let dmabuf_formats = renderer.dmabuf_formats().cloned().collect::<Vec<_>>();
state
.common
.dmabuf_state
.create_global::<State>(dh, dmabuf_formats);
}
Err(err) => warn!(?err, "Unable to initialize bind display to EGL."),
};
if let Err(err) = renderer.bind_wl_display(dh) {
warn!(
?err,
"Unable to initialize bind display to EGL. Some older clients may not work correctly."
)
}
let dmabuf_formats = renderer.dmabuf_formats().cloned().collect::<Vec<_>>();
let default_feedback = DmabufFeedbackBuilder::new(render_node.dev_id(), dmabuf_formats.clone())
.build()
.unwrap();
state
.common
.dmabuf_state
.create_global_with_default_feedback::<State>(dh, &default_feedback);
info!("EGL hardware-acceleration enabled.");
Ok(())
}

View file

@ -1017,8 +1017,7 @@ impl State {
&self
.common
.xwayland_state
.values()
.next()
.as_ref()
.map(|s| format!(":{}", s.display))
.unwrap_or(String::new()),
)

View file

@ -78,13 +78,7 @@ pub fn setup_socket(handle: LoopHandle<Data>, state: &State) -> Result<()> {
.into_string()
.map_err(|_| anyhow!("wayland socket is no valid utf-8 string?"))?,
);
if let Some(display) = state
.common
.xwayland_state
.values()
.next()
.map(|s| s.display)
{
if let Some(display) = state.common.xwayland_state.as_ref().map(|s| s.display) {
env.insert(String::from("DISPLAY"), format!(":{}", display));
}
let message = serde_json::to_string(&Message::SetEnv { variables: env })

View file

@ -131,7 +131,7 @@ impl Shell {
fn update_active<'a, 'b>(
&mut self,
seats: impl Iterator<Item = &'a Seat<State>>,
xwms: impl Iterator<Item = &'b mut XWaylandState>,
mut xwm: Option<&'b mut XWaylandState>,
) {
// update activate status
let focused_windows = seats
@ -144,16 +144,13 @@ impl Shell {
})
.collect::<Vec<_>>();
let mut xwms = xwms.collect::<Vec<_>>();
for output in self.outputs.iter() {
let workspace = self.workspaces.active_mut(output);
for focused in focused_windows.iter() {
if workspace.floating_layer.mapped().any(|m| m == focused) {
if let CosmicSurface::X11(window) = focused.active_window() {
for xwm in xwms.iter_mut().flat_map(|state| state.xwm.as_mut()) {
if Some(xwm.id()) == window.xwm_id() {
let _ = xwm.raise_window(&window);
}
if let Some(xwm) = xwm.as_mut().and_then(|state| state.xwm.as_mut()) {
let _ = xwm.raise_window(&window);
}
}
workspace.floating_layer.space.raise_element(focused, true);
@ -179,7 +176,7 @@ impl Common {
state
.common
.shell
.update_active(seats.iter(), state.common.xwayland_state.values_mut());
.update_active(seats.iter(), state.common.xwayland_state.as_mut());
}
pub fn refresh_focus(state: &mut State) {
@ -274,6 +271,6 @@ impl Common {
state
.common
.shell
.update_active(seats.iter(), state.common.xwayland_state.values_mut())
.update_active(seats.iter(), state.common.xwayland_state.as_mut())
}
}

View file

@ -1085,13 +1085,12 @@ impl Shell {
.map(mapped.clone(), &seat, focus_stack.iter());
}
if let CosmicSurface::X11(surface) = window {
if let CosmicSurface::X11(_) = window {
if let Some(xwm) = state
.common
.xwayland_state
.values_mut()
.flat_map(|state| state.xwm.as_mut())
.find(|xwm| Some(xwm.id()) == surface.xwm_id())
.as_mut()
.and_then(|state| state.xwm.as_mut())
{
if let Err(err) = xwm.update_stacking_order_downwards(workspace.mapped()) {
warn!(?err, "Failed to update Xwayland stacking order.");

View file

@ -437,7 +437,7 @@ impl Workspace {
renderer: &mut R,
output: &Output,
override_redirect_windows: &[X11Surface],
xwm_state: impl Iterator<Item = &'a mut XWaylandState>,
xwm_state: Option<&'a mut XWaylandState>,
draw_focus_indicator: Option<&Seat<State>>,
exclude_workspace_overview: bool,
) -> Result<Vec<WorkspaceRenderElement<R>>, OutputNotMapped>
@ -502,7 +502,7 @@ impl Workspace {
fullscreen, renderer, (0, 0).into(), output_scale.into()
));
for xwm in xwm_state.flat_map(|state| state.xwm.as_mut()) {
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
if let Err(err) =
xwm.update_stacking_order_upwards(render_elements.iter().rev().map(|e| e.id()))
{
@ -584,7 +584,7 @@ impl Workspace {
.map(WorkspaceRenderElement::from),
);
for xwm in xwm_state.flat_map(|state| state.xwm.as_mut()) {
if let Some(xwm) = xwm_state.and_then(|state| state.xwm.as_mut()) {
if let Err(err) =
xwm.update_stacking_order_upwards(render_elements.iter().rev().map(|e| e.id()))
{

View file

@ -57,7 +57,7 @@ use smithay::{
};
use tracing::error;
use std::{cell::RefCell, collections::HashMap, ffi::OsString, time::Duration};
use std::{cell::RefCell, ffi::OsString, time::Duration};
use std::{collections::VecDeque, time::Instant};
pub struct ClientState {
@ -118,7 +118,7 @@ pub struct Common {
pub xdg_decoration_state: XdgDecorationState,
// xwayland state
pub xwayland_state: HashMap<Option<DrmNode>, XWaylandState>,
pub xwayland_state: Option<XWaylandState>,
}
pub enum BackendData {
@ -290,7 +290,7 @@ impl State {
kde_decoration_state,
xdg_decoration_state,
xwayland_state: HashMap::new(),
xwayland_state: None,
},
backend: BackendData::Unset,
}

View file

@ -15,8 +15,7 @@ pub fn ready(state: &State) {
&state
.common
.xwayland_state
.values()
.next()
.as_ref()
.map(|s| format!(":{}", s.display))
.unwrap_or(String::new()),
)

View file

@ -58,8 +58,8 @@ impl DataDeviceHandler for State {
}
fn new_selection(&mut self, source: Option<WlDataSource>) {
for xstate in self.common.xwayland_state.values_mut() {
if let Some(xwm) = xstate.xwm.as_mut() {
if let Some(state) = self.common.xwayland_state.as_mut() {
if let Some(xwm) = state.xwm.as_mut() {
if let Some(source) = &source {
if let Ok(Err(err)) = with_source_metadata(source, |metadata| {
xwm.new_selection(
@ -80,14 +80,13 @@ impl DataDeviceHandler for State {
&mut self,
mime_type: String,
fd: OwnedFd,
user_data: &Self::SelectionUserData,
_user_data: &Self::SelectionUserData,
) {
if let Some(xwm) = self
.common
.xwayland_state
.values_mut()
.flat_map(|xstate| xstate.xwm.as_mut())
.find(|xwm| &xwm.id() == user_data)
.as_mut()
.and_then(|xstate| xstate.xwm.as_mut())
{
if let Err(err) = xwm.send_selection(
SelectionType::Clipboard,

View file

@ -17,8 +17,8 @@ impl PrimarySelectionHandler for State {
}
fn new_selection(&mut self, source: Option<ZwpPrimarySelectionSourceV1>) {
for xstate in self.common.xwayland_state.values_mut() {
if let Some(xwm) = xstate.xwm.as_mut() {
if let Some(state) = self.common.xwayland_state.as_mut() {
if let Some(xwm) = state.xwm.as_mut() {
if let Some(source) = &source {
if let Ok(Err(err)) = with_source_metadata(source, |metadata| {
xwm.new_selection(SelectionType::Primary, Some(metadata.mime_types.clone()))
@ -36,14 +36,13 @@ impl PrimarySelectionHandler for State {
&mut self,
mime_type: String,
fd: OwnedFd,
user_data: &Self::SelectionUserData,
_user_data: &Self::SelectionUserData,
) {
if let Some(xwm) = self
.common
.xwayland_state
.values_mut()
.flat_map(|xstate| xstate.xwm.as_mut())
.find(|xwm| &xwm.id() == user_data)
.as_mut()
.and_then(|xstate| xstate.xwm.as_mut())
{
if let Err(err) = xwm.send_selection(
SelectionType::Primary,

View file

@ -37,8 +37,8 @@ pub struct XWaylandState {
}
impl State {
pub fn launch_xwayland(&mut self, drm_node: Option<DrmNode>) {
if self.common.xwayland_state.contains_key(&drm_node) {
pub fn launch_xwayland(&mut self, render_node: Option<DrmNode>) {
if self.common.xwayland_state.is_some() {
return;
}
@ -81,14 +81,11 @@ impl State {
);
}
let mut xwayland_state =
data.state.common.xwayland_state.get_mut(&drm_node).unwrap();
let mut xwayland_state = data.state.common.xwayland_state.as_mut().unwrap();
xwayland_state.xwm = Some(wm);
}
XWaylandEvent::Exited => {
if let Some(mut xwayland_state) =
data.state.common.xwayland_state.remove(&drm_node)
{
if let Some(mut xwayland_state) = data.state.common.xwayland_state.take() {
xwayland_state.xwm = None;
}
}
@ -105,21 +102,18 @@ impl State {
None,
std::iter::empty::<(OsString, OsString)>(),
//vec![("WAYLAND_DEBUG", "client")].into_iter(),
|map| {
if let Some(node) = drm_node {
map.insert_if_missing(|| node);
|user_data| {
if let Some(node) = render_node {
user_data.insert_if_missing(|| node);
}
},
) {
Ok(display) => {
self.common.xwayland_state.insert(
drm_node,
XWaylandState {
xwayland,
xwm: None,
display,
},
);
self.common.xwayland_state = Some(XWaylandState {
xwayland,
xwm: None,
display,
});
}
Err(err) => {
error!(?err, "Failed to start Xwayland.");
@ -130,13 +124,12 @@ impl State {
}
impl XwmHandler for Data {
fn xwm_state(&mut self, xwm: XwmId) -> &mut X11Wm {
fn xwm_state(&mut self, _xwm: XwmId) -> &mut X11Wm {
self.state
.common
.xwayland_state
.values_mut()
.flat_map(|state| &mut state.xwm)
.find(|wm| wm.id() == xwm)
.as_mut()
.and_then(|state| state.xwm.as_mut())
.unwrap()
}