xwm: Don't do multiple
This commit is contained in:
parent
7caae686fe
commit
659933b039
14 changed files with 114 additions and 90 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1017,8 +1017,7 @@ impl State {
|
|||
&self
|
||||
.common
|
||||
.xwayland_state
|
||||
.values()
|
||||
.next()
|
||||
.as_ref()
|
||||
.map(|s| format!(":{}", s.display))
|
||||
.unwrap_or(String::new()),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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 })
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
|
|
|||
|
|
@ -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()))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue