Merge pull request #186 from pop-os/update-smithay_jammy

chore: Update deps
This commit is contained in:
Victoria Brekenfeld 2023-10-02 23:19:28 +02:00 committed by GitHub
commit a149b4262f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 1332 additions and 1126 deletions

1343
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -11,11 +11,10 @@ members = [
] ]
[dependencies] [dependencies]
apply = "0.3.0"
anyhow = { version = "1.0.51", features = ["backtrace"] } anyhow = { version = "1.0.51", features = ["backtrace"] }
bitflags = "1.3.2" bitflags = "2.4"
bytemuck = "1.12" bytemuck = "1.12"
calloop = { version = "0.10.1", features = ["executor"] } calloop = { version = "0.12.2", features = ["executor"] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
sendfd = "0.4.1" sendfd = "0.4.1"
@ -28,19 +27,19 @@ log-panics = { version = "2", features = ["with-backtrace"] }
thiserror = "1.0.26" thiserror = "1.0.26"
regex = "1" regex = "1"
xcursor = "0.3.3" xcursor = "0.3.3"
xkbcommon = "0.4" xkbcommon = "0.6"
indexmap = "1.8.0" indexmap = "2.0"
xdg = "^2.1" xdg = "^2.1"
ron = "0.7" ron = "0.7"
libsystemd = { version = "0.5", optional = true } libsystemd = { version = "0.5", optional = true }
wayland-backend = "0.1.0" wayland-backend = "0.3.0"
wayland-scanner = "0.30.0" wayland-scanner = "0.31.0"
cosmic-comp-config = { path = "cosmic-comp-config" } cosmic-comp-config = { path = "cosmic-comp-config" }
cosmic-config = { git = "https://github.com/pop-os/libcosmic/", rev = "4895b0c", features = ["calloop"] } cosmic-config = { git = "https://github.com/pop-os/libcosmic/", rev = "f91287d", features = ["calloop"] }
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] } cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", branch = "main", default-features = false, features = ["server"] }
libcosmic = { git = "https://github.com/pop-os/libcosmic/", rev = "4895b0c", default-features = false } libcosmic = { git = "https://github.com/pop-os/libcosmic/", rev = "f91287d", default-features = false }
iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic/", rev = "4895b0c" } iced_tiny_skia = { git = "https://github.com/pop-os/libcosmic/", rev = "f91287d" }
tiny-skia = "0.9" tiny-skia = "0.10"
ordered-float = "3.0" ordered-float = "3.0"
glow = "0.11.2" glow = "0.11.2"
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "tracing-log"] } tracing-subscriber = { version = "0.3.16", features = ["env-filter", "tracing-log"] }
@ -61,13 +60,13 @@ branch = "feature/copy_clone"
[dependencies.smithay] [dependencies.smithay]
version = "0.3" version = "0.3"
git = "https://github.com/smithay/smithay.git" git = "https://github.com/smithay/smithay.git"
rev = "58d5bdc" rev = "74ef59a3f"
default-features = false default-features = false
features = ["backend_drm", "backend_gbm", "backend_egl", "backend_libinput", "backend_session_libseat", "backend_udev", "backend_winit", "backend_vulkan", "backend_x11", "desktop", "use_system_lib", "renderer_glow", "renderer_multi", "wayland_frontend", "xwayland"] features = ["backend_drm", "backend_gbm", "backend_egl", "backend_libinput", "backend_session_libseat", "backend_udev", "backend_winit", "backend_vulkan", "backend_x11", "desktop", "use_system_lib", "renderer_glow", "renderer_multi", "wayland_frontend", "xwayland"]
[dependencies.smithay-egui] [dependencies.smithay-egui]
git = "https://github.com/Smithay/smithay-egui.git" git = "https://github.com/Smithay/smithay-egui.git"
rev = "dab5c1b" rev = "114d8db6"
features = ["svg"] features = ["svg"]
optional = true optional = true
@ -87,4 +86,4 @@ debug = true
lto = "fat" lto = "fat"
[patch."https://github.com/Smithay/smithay.git"] [patch."https://github.com/Smithay/smithay.git"]
smithay = { git = "https://github.com/smithay//smithay", rev = "d3e1ef9" } smithay = { git = "https://github.com/smithay//smithay", rev = "74ef59a3f" }

View file

@ -6,7 +6,7 @@ use crate::{
backend::render::{workspace_elements, CLEAR_COLOR}, backend::render::{workspace_elements, CLEAR_COLOR},
config::OutputConfig, config::OutputConfig,
shell::Shell, shell::Shell,
state::{BackendData, ClientState, Common, Data, Fps, SurfaceDmabufFeedback}, state::{BackendData, ClientState, Common, Fps, SurfaceDmabufFeedback},
utils::prelude::*, utils::prelude::*,
wayland::{ wayland::{
handlers::screencopy::{render_session, UserdataExt}, handlers::screencopy::{render_session, UserdataExt},
@ -157,7 +157,7 @@ pub type GbmDrmCompositor = DrmCompositor<
pub fn init_backend( pub fn init_backend(
dh: &DisplayHandle, dh: &DisplayHandle,
event_loop: &mut EventLoop<'static, Data>, event_loop: &mut EventLoop<'static, State>,
state: &mut State, state: &mut State,
) -> Result<()> { ) -> Result<()> {
let (session, notifier) = LibSeatSession::new().context("Failed to acquire session")?; let (session, notifier) = LibSeatSession::new().context("Failed to acquire session")?;
@ -172,21 +172,21 @@ pub fn init_backend(
let libinput_event_source = event_loop let libinput_event_source = event_loop
.handle() .handle()
.insert_source(libinput_backend, move |mut event, _, data| { .insert_source(libinput_backend, move |mut event, _, state| {
if let InputEvent::DeviceAdded { ref mut device } = &mut event { if let InputEvent::DeviceAdded { ref mut device } = &mut event {
data.state.common.config.read_device(device); state.common.config.read_device(device);
data.state state
.backend .backend
.kms() .kms()
.input_devices .input_devices
.insert(device.name().into(), device.clone()); .insert(device.name().into(), device.clone());
} else if let InputEvent::DeviceRemoved { device } = &event { } else if let InputEvent::DeviceRemoved { device } = &event {
data.state.backend.kms().input_devices.remove(device.name()); state.backend.kms().input_devices.remove(device.name());
} }
data.state.process_input_event(event, true); state.process_input_event(event, true);
for output in data.state.common.shell.outputs() { for output in state.common.shell.outputs() {
if let Err(err) = data.state.backend.kms().schedule_render( if let Err(err) = state.backend.kms().schedule_render(
&data.state.common.event_loop_handle, &state.common.event_loop_handle,
output, output,
None, None,
None, None,
@ -236,19 +236,17 @@ pub fn init_backend(
}; };
info!("Using {} as primary gpu for rendering.", primary); info!("Using {} as primary gpu for rendering.", primary);
let udev_dispatcher = Dispatcher::new(udev_backend, move |event, _, data: &mut Data| { let udev_dispatcher = Dispatcher::new(udev_backend, move |event, _, state: &mut State| {
let dh = state.common.display_handle.clone();
match match event { match match event {
UdevEvent::Added { device_id, path } => data UdevEvent::Added { device_id, path } => state
.state .device_added(device_id, path, &dh, true)
.device_added(device_id, path, &data.display.handle(), true)
.with_context(|| format!("Failed to add drm device: {}", device_id)), .with_context(|| format!("Failed to add drm device: {}", device_id)),
UdevEvent::Changed { device_id } => data UdevEvent::Changed { device_id } => state
.state
.device_changed(device_id) .device_changed(device_id)
.with_context(|| format!("Failed to update drm device: {}", device_id)), .with_context(|| format!("Failed to update drm device: {}", device_id)),
UdevEvent::Removed { device_id } => data UdevEvent::Removed { device_id } => state
.state .device_removed(device_id, &dh)
.device_removed(device_id, &data.display.handle())
.with_context(|| format!("Failed to remove drm device: {}", device_id)), .with_context(|| format!("Failed to remove drm device: {}", device_id)),
} { } {
Ok(()) => { Ok(()) => {
@ -269,16 +267,16 @@ pub fn init_backend(
let dispatcher = udev_dispatcher.clone(); let dispatcher = udev_dispatcher.clone();
let session_event_source = event_loop let session_event_source = event_loop
.handle() .handle()
.insert_source(notifier, move |event, &mut (), data| match event { .insert_source(notifier, move |event, &mut (), state| match event {
SessionEvent::ActivateSession => { SessionEvent::ActivateSession => {
if let Err(err) = libinput_context.resume() { if let Err(err) = libinput_context.resume() {
error!(?err, "Failed to resume libinput context."); error!(?err, "Failed to resume libinput context.");
} }
for device in data.state.backend.kms().devices.values() { for device in state.backend.kms().devices.values() {
device.drm.activate(); device.drm.activate();
} }
let dispatcher = dispatcher.clone(); let dispatcher = dispatcher.clone();
handle.insert_idle(move |data| { handle.insert_idle(move |state| {
for (dev, path) in dispatcher.as_source_ref().device_list() { for (dev, path) in dispatcher.as_source_ref().device_list() {
let drm_node = match DrmNode::from_dev_id(dev) { let drm_node = match DrmNode::from_dev_id(dev) {
Ok(node) => node, Ok(node) => node,
@ -287,32 +285,27 @@ pub fn init_backend(
continue; continue;
} }
}; };
if data.state.backend.kms().devices.contains_key(&drm_node) { if state.backend.kms().devices.contains_key(&drm_node) {
if let Err(err) = data.state.device_changed(dev) { if let Err(err) = state.device_changed(dev) {
error!(?err, "Failed to update drm device {}.", path.display(),); error!(?err, "Failed to update drm device {}.", path.display(),);
} }
} else { } else {
if let Err(err) = data.state.device_added( let dh = state.common.display_handle.clone();
dev, if let Err(err) = state.device_added(dev, path.into(), &dh, true) {
path.into(),
&data.display.handle(),
true,
) {
error!(?err, "Failed to add drm device {}.", path.display(),); error!(?err, "Failed to add drm device {}.", path.display(),);
} }
} }
} }
let seats = data.state.common.seats().cloned().collect::<Vec<_>>(); let seats = state.common.seats().cloned().collect::<Vec<_>>();
data.state.common.config.read_outputs( state.common.config.read_outputs(
&mut data.state.common.output_configuration_state, &mut state.common.output_configuration_state,
&mut data.state.backend, &mut state.backend,
&mut data.state.common.shell, &mut state.common.shell,
seats.into_iter(), seats.into_iter(),
&data.state.common.event_loop_handle, &state.common.event_loop_handle,
); );
for surface in data for surface in state
.state
.backend .backend
.kms() .kms()
.devices .devices
@ -322,10 +315,10 @@ pub fn init_backend(
surface.scheduled = false; surface.scheduled = false;
surface.pending = false; surface.pending = false;
} }
for output in data.state.common.shell.outputs() { for output in state.common.shell.outputs() {
let sessions = output.pending_buffers().collect::<Vec<_>>(); let sessions = output.pending_buffers().collect::<Vec<_>>();
if let Err(err) = data.state.backend.kms().schedule_render( if let Err(err) = state.backend.kms().schedule_render(
&data.state.common.event_loop_handle, &state.common.event_loop_handle,
output, output,
None, None,
if !sessions.is_empty() { if !sessions.is_empty() {
@ -346,12 +339,12 @@ pub fn init_backend(
} }
SessionEvent::PauseSession => { SessionEvent::PauseSession => {
libinput_context.suspend(); libinput_context.suspend();
for device in data.state.backend.kms().devices.values_mut() { for device in state.backend.kms().devices.values_mut() {
device.drm.pause(); device.drm.pause();
for surface in device.surfaces.values_mut() { for surface in device.surfaces.values_mut() {
surface.surface = None; surface.surface = None;
if let Some(token) = surface.render_timer_token.take() { if let Some(token) = surface.render_timer_token.take() {
data.state.common.event_loop_handle.remove(token); state.common.event_loop_handle.remove(token);
} }
surface.scheduled = false; surface.scheduled = false;
} }
@ -466,10 +459,10 @@ impl State {
.event_loop_handle .event_loop_handle
.insert_source( .insert_source(
notifier, notifier,
move |event, metadata, data: &mut Data| match event { move |event, metadata, state: &mut State| match event {
DrmEvent::VBlank(crtc) => { DrmEvent::VBlank(crtc) => {
let rescheduled = if let Some(device) = let rescheduled = if let Some(device) =
data.state.backend.kms().devices.get_mut(&drm_node) state.backend.kms().devices.get_mut(&drm_node)
{ {
if let Some(surface) = device.surfaces.get_mut(&crtc) { if let Some(surface) = device.surfaces.get_mut(&crtc) {
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
@ -497,7 +490,7 @@ impl State {
) )
} else { } else {
( (
data.state.common.clock.now(), state.common.clock.now(),
wp_presentation_feedback::Kind::Vsync, wp_presentation_feedback::Kind::Vsync,
) )
}; };
@ -520,7 +513,7 @@ impl State {
surface.pending = false; surface.pending = false;
let animations_going = let animations_going =
data.state.common.shell.animations_going(); state.common.shell.animations_going();
let animation_diff = std::mem::replace( let animation_diff = std::mem::replace(
&mut surface.last_animation_state, &mut surface.last_animation_state,
animations_going, animations_going,
@ -549,7 +542,7 @@ impl State {
if let Some((output, avg_rendertime)) = rescheduled { if let Some((output, avg_rendertime)) = rescheduled {
let mut scheduled_sessions = let mut scheduled_sessions =
data.state.workspace_session_for_output(&output); state.workspace_session_for_output(&output);
let mut output_sessions = output.pending_buffers().peekable(); let mut output_sessions = output.pending_buffers().peekable();
if output_sessions.peek().is_some() { if output_sessions.peek().is_some() {
scheduled_sessions scheduled_sessions
@ -559,8 +552,8 @@ impl State {
let estimated_rendertime = let estimated_rendertime =
std::cmp::max(avg_rendertime, MIN_RENDER_TIME); std::cmp::max(avg_rendertime, MIN_RENDER_TIME);
if let Err(err) = data.state.backend.kms().schedule_render( if let Err(err) = state.backend.kms().schedule_render(
&data.state.common.event_loop_handle, &state.common.event_loop_handle,
&output, &output,
Some(estimated_rendertime), Some(estimated_rendertime),
scheduled_sessions, scheduled_sessions,
@ -1255,7 +1248,7 @@ impl KmsState {
seats: impl Iterator<Item = Seat<State>>, 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<'_, State>,
) -> Result<(), anyhow::Error> { ) -> Result<(), anyhow::Error> {
let recreated = if let Some(device) = self let recreated = if let Some(device) = self
.devices .devices
@ -1464,7 +1457,7 @@ impl KmsState {
pub fn schedule_render( pub fn schedule_render(
&mut self, &mut self,
loop_handle: &LoopHandle<'_, Data>, loop_handle: &LoopHandle<'_, State>,
output: &Output, output: &Output,
estimated_rendertime: Option<Duration>, estimated_rendertime: Option<Duration>,
mut screencopy_sessions: Option<Vec<(ScreencopySession, BufferParams)>>, mut screencopy_sessions: Option<Vec<(ScreencopySession, BufferParams)>>,
@ -1477,9 +1470,9 @@ impl KmsState {
{ {
if surface.surface.is_none() { if surface.surface.is_none() {
if let Some(sessions) = screencopy_sessions { if let Some(sessions) = screencopy_sessions {
loop_handle.insert_idle(move |data| { loop_handle.insert_idle(move |state| {
for (session, params) in sessions.into_iter() { for (session, params) in sessions.into_iter() {
data.state.common.still_pending(session, params); state.common.still_pending(session, params);
} }
}); });
} }
@ -1500,8 +1493,8 @@ impl KmsState {
.saturating_sub(estimated_rendertime.unwrap()), .saturating_sub(estimated_rendertime.unwrap()),
) )
}, },
move |_time, _, data| { move |_time, _, state| {
let backend = data.state.backend.kms(); let backend = state.backend.kms();
let (mut device, mut other) = backend let (mut device, mut other) = backend
.devices .devices
.iter_mut() .iter_mut()
@ -1511,12 +1504,12 @@ impl KmsState {
if let Some(surface) = target_device.surfaces.get_mut(&crtc) { if let Some(surface) = target_device.surfaces.get_mut(&crtc) {
let target_node = target_device.render_node; let target_node = target_device.render_node;
let render_node = render_node_for_output( let render_node = render_node_for_output(
&data.display.handle(), &state.common.display_handle,
&surface.output, &surface.output,
target_node, target_node,
&data.state.common.shell, &state.common.shell,
); );
let state = &mut data.state.common; let common = &mut state.common;
let result = if render_node != target_node { let result = if render_node != target_node {
let render_device = &mut other let render_device = &mut other
@ -1531,7 +1524,7 @@ impl KmsState {
render_device.allocator.as_mut(), render_device.allocator.as_mut(),
)), )),
&target_node, &target_node,
state, common,
screencopy_sessions.as_deref(), screencopy_sessions.as_deref(),
) )
} else { } else {
@ -1539,7 +1532,7 @@ impl KmsState {
&mut backend.api, &mut backend.api,
None, None,
&target_node, &target_node,
state, common,
screencopy_sessions.as_deref(), screencopy_sessions.as_deref(),
) )
}; };
@ -1564,7 +1557,7 @@ impl KmsState {
if let Some(sessions) = screencopy_sessions.as_mut() { if let Some(sessions) = screencopy_sessions.as_mut() {
for (session, params) in sessions.drain(..) { for (session, params) in sessions.drain(..) {
data.state.common.still_pending(session, params); state.common.still_pending(session, params);
} }
} }
TimeoutAction::Drop TimeoutAction::Drop
@ -1573,9 +1566,9 @@ impl KmsState {
surface.scheduled = true; surface.scheduled = true;
} else { } else {
if let Some(sessions) = screencopy_sessions { if let Some(sessions) = screencopy_sessions {
loop_handle.insert_idle(|data| { loop_handle.insert_idle(|state| {
for (session, params) in sessions.into_iter() { for (session, params) in sessions.into_iter() {
data.state.common.still_pending(session, params); state.common.still_pending(session, params);
} }
}); });
} }

View file

@ -19,10 +19,7 @@ use smithay::{
use std::sync::Arc; use std::sync::Arc;
use tracing::{info, warn}; use tracing::{info, warn};
use crate::{ use crate::state::{ClientState, State};
state::{ClientState, Data},
utils::prelude::*,
};
#[derive(Debug)] #[derive(Debug)]
pub struct Socket { pub struct Socket {
@ -96,10 +93,10 @@ impl State {
let token = self let token = self
.common .common
.event_loop_handle .event_loop_handle
.insert_source(listener, move |client_stream, _, data: &mut Data| { .insert_source(listener, move |client_stream, _, state: &mut State| {
if let Err(err) = data.display.handle().insert_client( if let Err(err) = state.common.display_handle.insert_client(
client_stream, client_stream,
Arc::new(data.state.new_client_state_with_node(render_node)), Arc::new(state.new_client_state_with_node(render_node)),
) { ) {
warn!( warn!(
socket_name = socket_name_clone, socket_name = socket_name_clone,

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::state::{Data, State}; use crate::state::State;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use smithay::reexports::{calloop::EventLoop, wayland_server::DisplayHandle}; use smithay::reexports::{calloop::EventLoop, wayland_server::DisplayHandle};
use tracing::{info, warn}; use tracing::{info, warn};
@ -15,7 +15,7 @@ pub mod x11;
pub fn init_backend_auto( pub fn init_backend_auto(
dh: &DisplayHandle, dh: &DisplayHandle,
event_loop: &mut EventLoop<'static, Data>, event_loop: &mut EventLoop<'static, State>,
state: &mut State, state: &mut State,
) -> Result<()> { ) -> Result<()> {
let res = match std::env::var("COSMIC_BACKEND") { let res = match std::env::var("COSMIC_BACKEND") {

View file

@ -4,7 +4,7 @@ use crate::{
backend::render, backend::render,
config::OutputConfig, config::OutputConfig,
input::Devices, input::Devices,
state::{BackendData, Common, Data}, state::{BackendData, Common},
utils::prelude::*, utils::prelude::*,
wayland::protocols::screencopy::{BufferParams, Session as ScreencopySession}, wayland::protocols::screencopy::{BufferParams, Session as ScreencopySession},
}; };
@ -147,7 +147,7 @@ impl WinitState {
pub fn init_backend( pub fn init_backend(
dh: &DisplayHandle, dh: &DisplayHandle,
event_loop: &mut EventLoop<Data>, event_loop: &mut EventLoop<State>,
state: &mut State, state: &mut State,
) -> Result<()> { ) -> Result<()> {
let (mut backend, mut input) = let (mut backend, mut input) =
@ -197,13 +197,8 @@ pub fn init_backend(
let mut token = Some( let mut token = Some(
event_loop event_loop
.handle() .handle()
.insert_source(render_source, move |_, _, data| { .insert_source(render_source, move |_, _, state| {
if let Err(err) = data if let Err(err) = state.backend.winit().render_output(&mut state.common) {
.state
.backend
.winit()
.render_output(&mut data.state.common)
{
error!(?err, "Failed to render frame."); error!(?err, "Failed to render frame.");
render_ping.ping(); render_ping.ping();
} }
@ -213,21 +208,18 @@ pub fn init_backend(
let event_loop_handle = event_loop.handle(); let event_loop_handle = event_loop.handle();
event_loop event_loop
.handle() .handle()
.insert_source(event_source, move |_, _, data| { .insert_source(event_source, move |_, _, state| {
match input.dispatch_new_events(|event| { match input
data.state.process_winit_event(event, &render_ping_handle) .dispatch_new_events(|event| state.process_winit_event(event, &render_ping_handle))
}) { {
Ok(_) => { Ok(_) => {
event_ping_handle.ping(); event_ping_handle.ping();
render_ping_handle.ping(); render_ping_handle.ping();
} }
Err(winit::WinitError::WindowClosed) => { Err(winit::WinitError::WindowClosed) => {
let output = data.state.backend.winit().output.clone(); let output = state.backend.winit().output.clone();
let seats = data.state.common.seats().cloned().collect::<Vec<_>>(); let seats = state.common.seats().cloned().collect::<Vec<_>>();
data.state state.common.shell.remove_output(&output, seats.into_iter());
.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);
} }

View file

@ -4,7 +4,7 @@ use crate::{
backend::render, backend::render,
config::OutputConfig, config::OutputConfig,
input::Devices, input::Devices,
state::{BackendData, Common, Data}, state::{BackendData, Common},
utils::prelude::*, utils::prelude::*,
wayland::protocols::screencopy::{BufferParams, Session as ScreencopySession}, wayland::protocols::screencopy::{BufferParams, Session as ScreencopySession},
}; };
@ -63,7 +63,7 @@ pub struct X11State {
} }
impl X11State { impl X11State {
pub fn add_window(&mut self, handle: LoopHandle<'_, Data>) -> Result<Output> { pub fn add_window(&mut self, handle: LoopHandle<'_, State>) -> Result<Output> {
let window = WindowBuilder::new() let window = WindowBuilder::new()
.title("COSMIC") .title("COSMIC")
.build(&self.handle) .build(&self.handle)
@ -124,15 +124,15 @@ impl X11State {
let (ping, source) = let (ping, source) =
ping::make_ping().with_context(|| "Failed to create output event loop source")?; ping::make_ping().with_context(|| "Failed to create output event loop source")?;
let _token = handle let _token = handle
.insert_source(source, move |_, _, data| { .insert_source(source, move |_, _, state| {
let x11_state = data.state.backend.x11(); let x11_state = state.backend.x11();
if let Some(surface) = x11_state if let Some(surface) = x11_state
.surfaces .surfaces
.iter_mut() .iter_mut()
.find(|s| s.output == output_ref) .find(|s| s.output == output_ref)
{ {
if let Err(err) = if let Err(err) =
surface.render_output(&mut x11_state.renderer, &mut data.state.common) surface.render_output(&mut x11_state.renderer, &mut state.common)
{ {
error!(?err, "Error rendering."); error!(?err, "Error rendering.");
} }
@ -333,7 +333,7 @@ fn try_gbm_allocator(fd: OwnedFd) -> Option<Allocator> {
pub fn init_backend( pub fn init_backend(
dh: &DisplayHandle, dh: &DisplayHandle,
event_loop: &mut EventLoop<Data>, event_loop: &mut EventLoop<State>,
state: &mut State, state: &mut State,
) -> Result<()> { ) -> Result<()> {
let backend = X11Backend::new().with_context(|| "Failed to initilize X11 backend")?; let backend = X11Backend::new().with_context(|| "Failed to initilize X11 backend")?;
@ -391,12 +391,11 @@ pub fn init_backend(
event_loop event_loop
.handle() .handle()
.insert_source(backend, move |event, _, data| match event { .insert_source(backend, move |event, _, state| 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();
for surface in data for surface in state
.state
.backend .backend
.x11() .x11()
.surfaces .surfaces
@ -406,13 +405,13 @@ pub fn init_backend(
surface.window.unmap(); surface.window.unmap();
outputs_removed.push(surface.output.clone()); outputs_removed.push(surface.output.clone());
} }
data.state state
.backend .backend
.x11() .x11()
.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 state
.common .common
.shell .shell
.remove_output(&output, seats.iter().cloned()); .remove_output(&output, seats.iter().cloned());
@ -427,8 +426,7 @@ pub fn init_backend(
size, size,
refresh: 60_000, refresh: 60_000,
}; };
if let Some(surface) = data if let Some(surface) = state
.state
.backend .backend
.x11() .x11()
.surfaces .surfaces
@ -449,8 +447,8 @@ pub fn init_backend(
output.change_current_state(Some(mode), None, None, None); output.change_current_state(Some(mode), None, None, None);
output.set_preferred(mode); output.set_preferred(mode);
layer_map_for_output(output).arrange(); layer_map_for_output(output).arrange();
data.state.common.output_configuration_state.update(); state.common.output_configuration_state.update();
data.state.common.shell.refresh_outputs(); state.common.shell.refresh_outputs();
surface.dirty = true; surface.dirty = true;
if !surface.pending { if !surface.pending {
surface.render.ping(); surface.render.ping();
@ -458,8 +456,7 @@ pub fn init_backend(
} }
} }
X11Event::Refresh { window_id } | X11Event::PresentCompleted { window_id } => { X11Event::Refresh { window_id } | X11Event::PresentCompleted { window_id } => {
if let Some(surface) = data if let Some(surface) = state
.state
.backend .backend
.x11() .x11()
.surfaces .surfaces
@ -473,7 +470,7 @@ pub fn init_backend(
} }
} }
} }
X11Event::Input(event) => data.state.process_x11_event(event), X11Event::Input(event) => state.process_x11_event(event),
}) })
.map_err(|_| anyhow::anyhow!("Failed to insert X11 Backend into event loop"))?; .map_err(|_| anyhow::anyhow!("Failed to insert X11 Backend into event loop"))?;

View file

@ -4,7 +4,7 @@ use crate::shell::{focus::FocusDirection, grabs::ResizeEdge, Direction, ResizeDi
use serde::Deserialize; use serde::Deserialize;
use smithay::{ use smithay::{
backend::input::KeyState, backend::input::KeyState,
input::keyboard::{keysyms as KeySyms, xkb::keysym_get_name, ModifiersState}, input::keyboard::{xkb::keysym_get_name, ModifiersState},
}; };
use std::collections::HashMap; use std::collections::HashMap;
@ -90,11 +90,11 @@ pub struct KeyPattern {
pub modifiers: KeyModifiers, pub modifiers: KeyModifiers,
/// The actual key, that was pressed /// The actual key, that was pressed
#[serde(deserialize_with = "deserialize_Keysym", default)] #[serde(deserialize_with = "deserialize_Keysym", default)]
pub key: Option<u32>, pub key: Option<Keysym>,
} }
impl KeyPattern { impl KeyPattern {
pub fn new(modifiers: impl Into<KeyModifiers>, key: Option<u32>) -> KeyPattern { pub fn new(modifiers: impl Into<KeyModifiers>, key: Option<Keysym>) -> KeyPattern {
KeyPattern { KeyPattern {
modifiers: modifiers.into(), modifiers: modifiers.into(),
key, key,
@ -174,7 +174,7 @@ pub enum Action {
fn insert_binding( fn insert_binding(
key_bindings: &mut HashMap<KeyPattern, Action>, key_bindings: &mut HashMap<KeyPattern, Action>,
modifiers: KeyModifiers, modifiers: KeyModifiers,
keys: impl Iterator<Item = u32>, keys: impl Iterator<Item = Keysym>,
action: Action, action: Action,
) { ) {
if !key_bindings.values().any(|a| a == &action) { if !key_bindings.values().any(|a| a == &action) {
@ -197,16 +197,16 @@ pub fn add_default_bindings(
let (workspace_previous, workspace_next, output_previous, output_next) = match workspace_layout let (workspace_previous, workspace_next, output_previous, output_next) = match workspace_layout
{ {
WorkspaceLayout::Horizontal => ( WorkspaceLayout::Horizontal => (
[KeySyms::KEY_Left, KeySyms::KEY_h], [Keysym::Left, Keysym::h],
[KeySyms::KEY_Right, KeySyms::KEY_l], [Keysym::Right, Keysym::l],
[KeySyms::KEY_Up, KeySyms::KEY_k], [Keysym::Up, Keysym::k],
[KeySyms::KEY_Down, KeySyms::KEY_j], [Keysym::Down, Keysym::j],
), ),
WorkspaceLayout::Vertical => ( WorkspaceLayout::Vertical => (
[KeySyms::KEY_Up, KeySyms::KEY_k], [Keysym::Up, Keysym::k],
[KeySyms::KEY_Down, KeySyms::KEY_j], [Keysym::Down, Keysym::j],
[KeySyms::KEY_Left, KeySyms::KEY_h], [Keysym::Left, Keysym::h],
[KeySyms::KEY_Right, KeySyms::KEY_l], [Keysym::Right, Keysym::l],
), ),
}; };

View file

@ -2,7 +2,7 @@
use crate::{ use crate::{
shell::{Shell, WorkspaceAmount}, shell::{Shell, WorkspaceAmount},
state::{BackendData, Data, State}, state::{BackendData, State},
wayland::protocols::output_configuration::OutputConfigurationState, wayland::protocols::output_configuration::OutputConfigurationState,
}; };
use cosmic_config::ConfigGet; use cosmic_config::ConfigGet;
@ -158,12 +158,12 @@ impl OutputConfig {
} }
impl Config { impl Config {
pub fn load(loop_handle: &LoopHandle<'_, Data>) -> Config { pub fn load(loop_handle: &LoopHandle<'_, State>) -> Config {
let config = cosmic_config::Config::new("com.system76.CosmicComp", 1).unwrap(); let config = cosmic_config::Config::new("com.system76.CosmicComp", 1).unwrap();
let source = cosmic_config::calloop::ConfigWatchSource::new(&config).unwrap(); let source = cosmic_config::calloop::ConfigWatchSource::new(&config).unwrap();
loop_handle loop_handle
.insert_source(source, |(config, keys), (), shared_data| { .insert_source(source, |(config, keys), (), state| {
config_changed(config, keys, &mut shared_data.state); config_changed(config, keys, state);
}) })
.expect("Failed to add cosmic-config to the event loop"); .expect("Failed to add cosmic-config to the event loop");
let xdg = xdg::BaseDirectories::new().ok(); let xdg = xdg::BaseDirectories::new().ok();
@ -260,7 +260,7 @@ impl Config {
backend: &mut BackendData, backend: &mut BackendData,
shell: &mut Shell, shell: &mut Shell,
seats: impl Iterator<Item = Seat<State>>, seats: impl Iterator<Item = Seat<State>>,
loop_handle: &LoopHandle<'_, Data>, loop_handle: &LoopHandle<'_, State>,
) { ) {
let seats = seats.collect::<Vec<_>>(); let seats = seats.collect::<Vec<_>>();
let outputs = output_state.outputs().collect::<Vec<_>>(); let outputs = output_state.outputs().collect::<Vec<_>>();

View file

@ -3,6 +3,7 @@
use super::{KeyModifier, KeyModifiers}; use super::{KeyModifier, KeyModifiers};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use smithay::reexports::x11rb::NO_SYMBOL;
pub use smithay::{ pub use smithay::{
backend::input::KeyState, backend::input::KeyState,
input::keyboard::{keysyms as KeySyms, Keysym, XkbConfig as WlXkbConfig}, input::keyboard::{keysyms as KeySyms, Keysym, XkbConfig as WlXkbConfig},
@ -65,20 +66,22 @@ where
let name = String::deserialize(deserializer)?; let name = String::deserialize(deserializer)?;
//let name = format!("KEY_{}", code); //let name = format!("KEY_{}", code);
match xkb::keysym_from_name(&name, xkb::KEYSYM_NO_FLAGS) { match xkb::keysym_from_name(&name, xkb::KEYSYM_NO_FLAGS) {
KeySyms::KEY_NoSymbol => match xkb::keysym_from_name(&name, xkb::KEYSYM_CASE_INSENSITIVE) { x if x.raw() == NO_SYMBOL => {
KeySyms::KEY_NoSymbol => Err(<D::Error as Error>::invalid_value( match xkb::keysym_from_name(&name, xkb::KEYSYM_CASE_INSENSITIVE) {
Unexpected::Str(&name), x if x.raw() == NO_SYMBOL => Err(<D::Error as Error>::invalid_value(
&"One of the keysym names of xkbcommon.h without the 'KEY_' prefix", Unexpected::Str(&name),
)), &"One of the keysym names of xkbcommon.h without the 'KEY_' prefix",
x => { )),
warn!( x => {
"Key-Binding '{}' only matched case insensitive for {:?}", warn!(
name, "Key-Binding '{}' only matched case insensitive for {:?}",
xkb::keysym_get_name(x) name,
); xkb::keysym_get_name(x)
Ok(Some(x)) );
Ok(Some(x))
}
} }
}, }
x => Ok(Some(x)), x => Ok(Some(x)),
} }
} }

View file

@ -25,7 +25,7 @@ use smithay::{
}, },
desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType}, desktop::{layer_map_for_output, space::SpaceElement, WindowSurfaceType},
input::{ input::{
keyboard::{keysyms, FilterResult, KeysymHandle, XkbConfig}, keyboard::{FilterResult, KeysymHandle, XkbConfig},
pointer::{ pointer::{
AxisFrame, ButtonEvent, CursorImageStatus, GestureHoldBeginEvent, GestureHoldEndEvent, AxisFrame, ButtonEvent, CursorImageStatus, GestureHoldBeginEvent, GestureHoldEndEvent,
GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent, GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent,
@ -51,6 +51,7 @@ use smithay::{
#[cfg(not(feature = "debug"))] #[cfg(not(feature = "debug"))]
use tracing::info; use tracing::info;
use tracing::{error, trace, warn}; use tracing::{error, trace, warn};
use xkbcommon::xkb::{Keycode, Keysym};
use std::{ use std::{
any::Any, any::Any,
@ -58,7 +59,6 @@ use std::{
collections::HashMap, collections::HashMap,
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use xkbcommon::xkb::KEY_XF86Switch_VT_12;
crate::utils::id_gen!(next_seat_id, SEAT_ID, SEAT_IDS); crate::utils::id_gen!(next_seat_id, SEAT_ID, SEAT_IDS);
@ -66,7 +66,7 @@ crate::utils::id_gen!(next_seat_id, SEAT_ID, SEAT_IDS);
pub struct SeatId(pub usize); pub struct SeatId(pub usize);
pub struct ActiveOutput(pub RefCell<Output>); pub struct ActiveOutput(pub RefCell<Output>);
#[derive(Default)] #[derive(Default)]
pub struct SupressedKeys(RefCell<Vec<(u32, Option<RegistrationToken>)>>); pub struct SupressedKeys(RefCell<Vec<(Keycode, Option<RegistrationToken>)>>);
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct ModifiersShortcutQueue(RefCell<Option<KeyPattern>>); pub struct ModifiersShortcutQueue(RefCell<Option<KeyPattern>>);
#[derive(Default)] #[derive(Default)]
@ -321,8 +321,8 @@ impl State {
if let Some(new_workspace) = other_w.iter_mut().find(|w| w.handle == new_descriptor.handle) { if let Some(new_workspace) = other_w.iter_mut().find(|w| w.handle == new_descriptor.handle) {
if let Some(focus) = TilingLayout::swap_trees(&mut old_workspace.tiling_layer, Some(&mut new_workspace.tiling_layer), &old_descriptor, &new_descriptor, &mut data.common.shell.toplevel_info_state) { if let Some(focus) = TilingLayout::swap_trees(&mut old_workspace.tiling_layer, Some(&mut new_workspace.tiling_layer), &old_descriptor, &new_descriptor, &mut data.common.shell.toplevel_info_state) {
let seat = seat.clone(); let seat = seat.clone();
data.common.event_loop_handle.insert_idle(move |data| { data.common.event_loop_handle.insert_idle(move |state| {
Common::set_focus(&mut data.state, Some(&focus), &seat, None); Common::set_focus(state, Some(&focus), &seat, None);
}); });
} }
old_workspace.refresh_focus_stack(); old_workspace.refresh_focus_stack();
@ -334,8 +334,8 @@ impl State {
if let Some(focus) = TilingLayout::swap_trees(&mut workspace.tiling_layer, None, &old_descriptor, &new_descriptor, &mut data.common.shell.toplevel_info_state) { if let Some(focus) = TilingLayout::swap_trees(&mut workspace.tiling_layer, None, &old_descriptor, &new_descriptor, &mut data.common.shell.toplevel_info_state) {
std::mem::drop(spaces); std::mem::drop(spaces);
let seat = seat.clone(); let seat = seat.clone();
data.common.event_loop_handle.insert_idle(move |data| { data.common.event_loop_handle.insert_idle(move |state| {
Common::set_focus(&mut data.state, Some(&focus), &seat, None); Common::set_focus(state, Some(&focus), &seat, None);
}); });
} }
workspace.refresh_focus_stack(); workspace.refresh_focus_stack();
@ -352,8 +352,8 @@ impl State {
if new_workspace.tiling_layer.windows().next().is_none() { if new_workspace.tiling_layer.windows().next().is_none() {
if let Some(focus) = TilingLayout::move_tree(&mut old_workspace.tiling_layer, &mut new_workspace.tiling_layer, &current_output, &new_workspace.handle, &seat, new_workspace.focus_stack.get(&seat).iter(), old_descriptor, &mut data.common.shell.toplevel_info_state) { if let Some(focus) = TilingLayout::move_tree(&mut old_workspace.tiling_layer, &mut new_workspace.tiling_layer, &current_output, &new_workspace.handle, &seat, new_workspace.focus_stack.get(&seat).iter(), old_descriptor, &mut data.common.shell.toplevel_info_state) {
let seat = seat.clone(); let seat = seat.clone();
data.common.event_loop_handle.insert_idle(move |data| { data.common.event_loop_handle.insert_idle(move |state| {
Common::set_focus(&mut data.state, Some(&focus), &seat, None); Common::set_focus(state, Some(&focus), &seat, None);
}); });
} }
old_workspace.refresh_focus_stack(); old_workspace.refresh_focus_stack();
@ -401,10 +401,10 @@ impl State {
data.common.shell.resize_mode() data.common.shell.resize_mode()
{ {
let resize_edge = match handle.modified_sym() { let resize_edge = match handle.modified_sym() {
keysyms::KEY_Left | keysyms::KEY_h | keysyms::KEY_H => Some(ResizeEdge::LEFT), Keysym::Left | Keysym::h | Keysym::H => Some(ResizeEdge::LEFT),
keysyms::KEY_Down | keysyms::KEY_j | keysyms::KEY_J => Some(ResizeEdge::BOTTOM), Keysym::Down | Keysym::j | Keysym::J => Some(ResizeEdge::BOTTOM),
keysyms::KEY_Up | keysyms::KEY_k | keysyms::KEY_K => Some(ResizeEdge::TOP), Keysym::Up | Keysym::k | Keysym::K => Some(ResizeEdge::TOP),
keysyms::KEY_Right | keysyms::KEY_l | keysyms::KEY_L => Some(ResizeEdge::RIGHT), Keysym::Right | Keysym::l | Keysym::L => Some(ResizeEdge::RIGHT),
_ => None, _ => None,
}; };
@ -415,7 +415,7 @@ impl State {
let action = Action::_ResizingInternal(direction, edge, state); let action = Action::_ResizingInternal(direction, edge, state);
let key_pattern = KeyPattern { let key_pattern = KeyPattern {
modifiers: modifiers.clone().into(), modifiers: modifiers.clone().into(),
key: Some(handle.raw_code()), key: Some(Keysym::new(handle.raw_code().raw())),
}; };
if state == KeyState::Released { if state == KeyState::Released {
@ -430,9 +430,9 @@ impl State {
let action_clone = action.clone(); let action_clone = action.clone();
let key_pattern_clone = key_pattern.clone(); let key_pattern_clone = key_pattern.clone();
let start = Instant::now(); let start = Instant::now();
loop_handle.insert_source(Timer::from_duration(Duration::from_millis(200)), move |current, _, data| { loop_handle.insert_source(Timer::from_duration(Duration::from_millis(200)), move |current, _, state| {
let duration = current.duration_since(start).as_millis(); let duration = current.duration_since(start).as_millis();
data.state.handle_action(action_clone.clone(), &seat_clone, serial, time.overflowing_add(duration as u32).0, key_pattern_clone.clone(), None); state.handle_action(action_clone.clone(), &seat_clone, serial, time.overflowing_add(duration as u32).0, key_pattern_clone.clone(), None);
calloop::timer::TimeoutAction::ToDuration(Duration::from_millis(25)) calloop::timer::TimeoutAction::ToDuration(Duration::from_millis(25))
}).ok() }).ok()
} else { None }; } else { None };
@ -482,11 +482,11 @@ impl State {
// Handle VT switches // Handle VT switches
if state == KeyState::Pressed if state == KeyState::Pressed
&& (keysyms::KEY_XF86Switch_VT_1..=KEY_XF86Switch_VT_12) && (Keysym::XF86_Switch_VT_1.raw() ..= Keysym::XF86_Switch_VT_12.raw())
.contains(&handle.modified_sym()) .contains(&handle.modified_sym().raw())
{ {
if let Err(err) = data.backend.kms().switch_vt( if let Err(err) = data.backend.kms().switch_vt(
(handle.modified_sym() - keysyms::KEY_XF86Switch_VT_1 (handle.modified_sym().raw() - Keysym::XF86_Switch_VT_1.raw()
+ 1) + 1)
as i32, as i32,
) { ) {

View file

@ -3,13 +3,13 @@
use smithay::{ use smithay::{
reexports::{ reexports::{
calloop::{generic::Generic, EventLoop, Interest, Mode, PostAction}, calloop::{generic::Generic, EventLoop, Interest, Mode, PostAction},
wayland_server::Display, wayland_server::{Display, DisplayHandle},
}, },
wayland::socket::ListeningSocketSource, wayland::socket::ListeningSocketSource,
}; };
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use std::{ffi::OsString, os::unix::prelude::AsRawFd, sync::Arc}; use std::{ffi::OsString, sync::Arc};
use tracing::{error, info, warn}; use tracing::{error, info, warn};
use crate::wayland::handlers::compositor::client_compositor_state; use crate::wayland::handlers::compositor::client_compositor_state;
@ -35,19 +35,18 @@ fn main() -> Result<()> {
info!("Cosmic starting up!"); info!("Cosmic starting up!");
// init event loop // init event loop
let mut event_loop = let mut event_loop = EventLoop::try_new().with_context(|| "Failed to initialize event loop")?;
EventLoop::try_new_high_precision().with_context(|| "Failed to initialize event loop")?;
// init wayland // init wayland
let (display, socket) = init_wayland_display(&mut event_loop)?; let (display, socket) = init_wayland_display(&mut event_loop)?;
// init state // init state
let mut state = state::State::new( let mut state = state::State::new(
&display.handle(), &display,
socket, socket,
event_loop.handle(), event_loop.handle(),
event_loop.get_signal(), event_loop.get_signal(),
); );
// init backend // init backend
backend::init_backend_auto(&display.handle(), &mut event_loop, &mut state)?; backend::init_backend_auto(&display, &mut event_loop, &mut state)?;
// potentially tell systemd we are setup now // potentially tell systemd we are setup now
#[cfg(feature = "systemd")] #[cfg(feature = "systemd")]
if let state::BackendData::Kms(_) = &state.backend { if let state::BackendData::Kms(_) = &state.backend {
@ -56,43 +55,43 @@ fn main() -> Result<()> {
// potentially tell the session we are setup now // potentially tell the session we are setup now
session::setup_socket(event_loop.handle(), &state)?; session::setup_socket(event_loop.handle(), &state)?;
let mut data = state::Data { display, state };
// run the event loop // run the event loop
event_loop.run(None, &mut data, |data| { event_loop.run(None, &mut state, |state| {
// shall we shut down? // shall we shut down?
if data.state.common.shell.outputs().next().is_none() || data.state.common.should_stop { if state.common.shell.outputs().next().is_none() || state.common.should_stop {
info!("Shutting down"); info!("Shutting down");
data.state.common.event_loop_signal.stop(); state.common.event_loop_signal.stop();
data.state.common.event_loop_signal.wakeup(); state.common.event_loop_signal.wakeup();
return; return;
} }
// trigger routines // trigger routines
let clients = data.state.common.shell.update_animations(); let clients = state.common.shell.update_animations();
{ {
let dh = data.display.handle(); let dh = state.common.display_handle.clone();
for client in clients.values() { for client in clients.values() {
client_compositor_state(&client).blocker_cleared(&mut data.state, &dh); client_compositor_state(&client).blocker_cleared(state, &dh);
} }
} }
data.state.common.shell.refresh(); state.common.shell.refresh();
state::Common::refresh_focus(&mut data.state); state::Common::refresh_focus(state);
// send out events // send out events
let _ = data.display.flush_clients(); let _ = state.common.display_handle.flush_clients();
})?; })?;
// drop eventloop & state before logger // drop eventloop & state before logger
std::mem::drop(event_loop); std::mem::drop(event_loop);
std::mem::drop(data); std::mem::drop(state);
Ok(()) Ok(())
} }
fn init_wayland_display( fn init_wayland_display(
event_loop: &mut EventLoop<state::Data>, event_loop: &mut EventLoop<state::State>,
) -> Result<(Display<state::State>, OsString)> { ) -> Result<(DisplayHandle, OsString)> {
let mut display = Display::new().unwrap(); let display = Display::new().unwrap();
let handle = display.handle();
let source = ListeningSocketSource::new_auto().unwrap(); let source = ListeningSocketSource::new_auto().unwrap();
let socket_name = source.socket_name().to_os_string(); let socket_name = source.socket_name().to_os_string();
@ -100,13 +99,13 @@ fn init_wayland_display(
event_loop event_loop
.handle() .handle()
.insert_source(source, |client_stream, _, data| { .insert_source(source, |client_stream, _, state| {
if let Err(err) = data.display.handle().insert_client( if let Err(err) = state.common.display_handle.insert_client(
client_stream, client_stream,
Arc::new(if cfg!(debug_assertions) { Arc::new(if cfg!(debug_assertions) {
data.state.new_privileged_client_state() state.new_privileged_client_state()
} else { } else {
data.state.new_client_state() state.new_client_state()
}), }),
) { ) {
warn!(?err, "Error adding wayland client"); warn!(?err, "Error adding wayland client");
@ -116,22 +115,20 @@ fn init_wayland_display(
event_loop event_loop
.handle() .handle()
.insert_source( .insert_source(
Generic::new( Generic::new(display, Interest::READ, Mode::Level),
display.backend().poll_fd().as_raw_fd(), move |_, display, state| {
Interest::READ, // SAFETY: We don't drop the display
Mode::Level, match unsafe { display.get_mut().dispatch_clients(state) } {
), Ok(_) => Ok(PostAction::Continue),
move |_, _, data: &mut state::Data| match data.display.dispatch_clients(&mut data.state) Err(err) => {
{ error!(?err, "I/O error on the Wayland display");
Ok(_) => Ok(PostAction::Continue), state.common.should_stop = true;
Err(err) => { Err(err)
error!(?err, "I/O error on the Wayland display"); }
data.state.common.should_stop = true;
Err(err)
} }
}, },
) )
.with_context(|| "Failed to init the wayland event source.")?; .with_context(|| "Failed to init the wayland event source.")?;
Ok((display, socket_name)) Ok((handle, socket_name))
} }

View file

@ -12,14 +12,14 @@ use std::{
collections::HashMap, collections::HashMap,
io::{Read, Write}, io::{Read, Write},
os::unix::{ os::unix::{
io::{AsRawFd, FromRawFd, RawFd}, io::{AsFd, BorrowedFd, FromRawFd, RawFd},
net::UnixStream, net::UnixStream,
}, },
sync::Arc, sync::Arc,
}; };
use tracing::{error, warn}; use tracing::{error, warn};
use crate::state::{Data, State}; use crate::state::State;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "message")] #[serde(rename_all = "snake_case", tag = "message")]
@ -34,9 +34,9 @@ struct StreamWrapper {
size: u16, size: u16,
read_bytes: usize, read_bytes: usize,
} }
impl AsRawFd for StreamWrapper { impl AsFd for StreamWrapper {
fn as_raw_fd(&self) -> RawFd { fn as_fd(&self) -> BorrowedFd<'_> {
self.stream.as_raw_fd() self.stream.as_fd()
} }
} }
impl From<UnixStream> for StreamWrapper { impl From<UnixStream> for StreamWrapper {
@ -50,7 +50,7 @@ impl From<UnixStream> for StreamWrapper {
} }
} }
pub fn setup_socket(handle: LoopHandle<Data>, state: &State) -> Result<()> { pub fn setup_socket(handle: LoopHandle<State>, state: &State) -> Result<()> {
if let Ok(fd_num) = std::env::var("COSMIC_SESSION_SOCK") { if let Ok(fd_num) = std::env::var("COSMIC_SESSION_SOCK") {
if let Ok(fd) = fd_num.parse::<RawFd>() { if let Ok(fd) = fd_num.parse::<RawFd>() {
// set CLOEXEC // set CLOEXEC
@ -94,7 +94,10 @@ pub fn setup_socket(handle: LoopHandle<Data>, state: &State) -> Result<()> {
handle.insert_source( handle.insert_source(
Generic::new(StreamWrapper::from(session_socket), Interest::READ, Mode::Level), Generic::new(StreamWrapper::from(session_socket), Interest::READ, Mode::Level),
move |_, stream, data: &mut crate::state::Data| { move |_, stream, state| {
// SAFETY: We don't drop the stream!
let stream = unsafe { stream.get_mut() };
if stream.size == 0 { if stream.size == 0 {
let mut len = [0u8; 2]; let mut len = [0u8; 2];
match stream.stream.read_exact(&mut len) { match stream.stream.read_exact(&mut len) {
@ -131,7 +134,7 @@ pub fn setup_socket(handle: LoopHandle<Data>, state: &State) -> Result<()> {
assert_eq!(received_count, count); assert_eq!(received_count, count);
for fd in fds.into_iter().take(received_count) { for fd in fds.into_iter().take(received_count) {
let stream = unsafe { UnixStream::from_raw_fd(fd) }; let stream = unsafe { UnixStream::from_raw_fd(fd) };
if let Err(err) = data.display.handle().insert_client(stream, Arc::new(data.state.new_privileged_client_state())) { if let Err(err) = state.common.display_handle.insert_client(stream, Arc::new(state.new_privileged_client_state())) {
warn!(?err, "Failed to add privileged client to display"); warn!(?err, "Failed to add privileged client to display");
} }
} }

View file

@ -539,7 +539,7 @@ impl CosmicMapped {
self.element = CosmicMappedInternal::Window(window); self.element = CosmicMappedInternal::Window(window);
} }
pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::State> {
match &self.element { match &self.element {
CosmicMappedInternal::Stack(stack) => stack.loop_handle(), CosmicMappedInternal::Stack(stack) => stack.loop_handle(),
CosmicMappedInternal::Window(window) => window.loop_handle(), CosmicMappedInternal::Window(window) => window.loop_handle(),

View file

@ -7,13 +7,13 @@ use crate::{
utils::iced::{IcedElement, Program}, utils::iced::{IcedElement, Program},
}; };
use apply::Apply;
use calloop::LoopHandle; use calloop::LoopHandle;
use cosmic::{ use cosmic::{
iced::widget::{column, container, horizontal_space, row, vertical_space}, iced::widget::{column, container, horizontal_space, row, vertical_space},
iced_core::{Background, Color, Length}, iced_core::{Background, Color, Length},
theme, theme,
widget::{icon, text}, widget::{icon::from_name, text},
Apply,
}; };
use smithay::utils::Size; use smithay::utils::Size;
@ -22,7 +22,7 @@ pub type ResizeIndicator = IcedElement<ResizeIndicatorInternal>;
pub fn resize_indicator( pub fn resize_indicator(
direction: ResizeDirection, direction: ResizeDirection,
config: &Config, config: &Config,
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
) -> ResizeIndicator { ) -> ResizeIndicator {
ResizeIndicator::new( ResizeIndicator::new(
ResizeIndicatorInternal { ResizeIndicatorInternal {
@ -64,26 +64,29 @@ impl Program for ResizeIndicatorInternal {
fn view(&self) -> crate::utils::iced::Element<'_, Self::Message> { fn view(&self) -> crate::utils::iced::Element<'_, Self::Message> {
let edges = self.edges.lock().unwrap(); let edges = self.edges.lock().unwrap();
let icon_container_style = || {
theme::Container::custom(|theme| container::Appearance {
icon_color: Some(Color::from(theme.cosmic().accent.on)),
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 18.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
})
};
column(vec![ column(vec![
if edges.contains(ResizeEdge::TOP) { if edges.contains(ResizeEdge::TOP) {
icon( from_name(if self.direction == ResizeDirection::Outwards {
if self.direction == ResizeDirection::Outwards { "go-up-symbolic"
"go-up-symbolic" } else {
} else { "go-down-symbolic"
"go-down-symbolic" })
}, .size(32)
32, .prefer_svg(true)
)
.force_svg(true)
.apply(container) .apply(container)
.padding(2) .padding(2)
.style(theme::Container::custom(|theme| container::Appearance { .style(icon_container_style())
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 18.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}))
.width(Length::Shrink) .width(Length::Shrink)
.apply(container) .apply(container)
.center_x() .center_x()
@ -94,24 +97,16 @@ impl Program for ResizeIndicatorInternal {
}, },
row(vec![ row(vec![
if edges.contains(ResizeEdge::LEFT) { if edges.contains(ResizeEdge::LEFT) {
icon( from_name(if self.direction == ResizeDirection::Outwards {
if self.direction == ResizeDirection::Outwards { "go-previous-symbolic"
"go-previous-symbolic" } else {
} else { "go-next-symbolic"
"go-next-symbolic" })
}, .size(32)
32, .prefer_svg(true)
)
.force_svg(true)
.apply(container) .apply(container)
.padding(4) .padding(4)
.style(theme::Container::custom(|theme| container::Appearance { .style(icon_container_style())
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 18.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}))
.width(Length::Shrink) .width(Length::Shrink)
.apply(container) .apply(container)
.center_y() .center_y()
@ -144,13 +139,7 @@ impl Program for ResizeIndicatorInternal {
.center_y() .center_y()
.padding(16) .padding(16)
.apply(container) .apply(container)
.style(theme::Container::custom(|theme| container::Appearance { .style(icon_container_style())
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 18.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}))
.width(Length::Shrink) .width(Length::Shrink)
.height(Length::Shrink) .height(Length::Shrink)
.apply(container) .apply(container)
@ -160,24 +149,16 @@ impl Program for ResizeIndicatorInternal {
.center_y() .center_y()
.into(), .into(),
if edges.contains(ResizeEdge::RIGHT) { if edges.contains(ResizeEdge::RIGHT) {
icon( from_name(if self.direction == ResizeDirection::Outwards {
if self.direction == ResizeDirection::Outwards { "go-next-symbolic"
"go-next-symbolic" } else {
} else { "go-previous-symbolic"
"go-previous-symbolic" })
}, .size(32)
32, .prefer_svg(true)
)
.force_svg(true)
.apply(container) .apply(container)
.padding(4) .padding(4)
.style(theme::Container::custom(|theme| container::Appearance { .style(icon_container_style())
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 18.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}))
.height(Length::Shrink) .height(Length::Shrink)
.apply(container) .apply(container)
.center_y() .center_y()
@ -191,24 +172,16 @@ impl Program for ResizeIndicatorInternal {
.height(Length::Fill) .height(Length::Fill)
.into(), .into(),
if edges.contains(ResizeEdge::BOTTOM) { if edges.contains(ResizeEdge::BOTTOM) {
icon( from_name(if self.direction == ResizeDirection::Outwards {
if self.direction == ResizeDirection::Outwards { "go-down-symbolic"
"go-down-symbolic" } else {
} else { "go-up-symbolic"
"go-up-symbolic" })
}, .size(32)
32, .prefer_svg(true)
)
.force_svg(true)
.apply(container) .apply(container)
.padding(4) .padding(4)
.style(theme::Container::custom(|theme| container::Appearance { .style(icon_container_style())
text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 18.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}))
.width(Length::Shrink) .width(Length::Shrink)
.apply(container) .apply(container)
.center_x() .center_x()

View file

@ -8,14 +8,13 @@ use crate::{
utils::prelude::SeatExt, utils::prelude::SeatExt,
wayland::handlers::screencopy::ScreencopySessions, wayland::handlers::screencopy::ScreencopySessions,
}; };
use apply::Apply;
use calloop::LoopHandle; use calloop::LoopHandle;
use cosmic::{ use cosmic::{
iced::{id::Id, widget as iced_widget}, iced::{id::Id, widget as iced_widget},
iced_core::{Background, BorderRadius, Color, Length}, iced_core::{Background, BorderRadius, Color, Length},
iced_runtime::Command, iced_runtime::Command,
iced_widget::scrollable::AbsoluteOffset, iced_widget::scrollable::AbsoluteOffset,
theme, widget as cosmic_widget, Element as CosmicElement, theme, widget as cosmic_widget, Apply, Element as CosmicElement,
}; };
use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType; use cosmic_protocols::screencopy::v1::server::zcosmic_screencopy_session_v1::InputType;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -122,14 +121,14 @@ pub enum Focus {
pub enum MoveResult { pub enum MoveResult {
Handled, Handled,
MoveOut(CosmicSurface, LoopHandle<'static, crate::state::Data>), MoveOut(CosmicSurface, LoopHandle<'static, crate::state::State>),
Default, Default,
} }
impl CosmicStack { impl CosmicStack {
pub fn new<I: Into<CosmicSurface>>( pub fn new<I: Into<CosmicSurface>>(
windows: impl Iterator<Item = I>, windows: impl Iterator<Item = I>,
handle: LoopHandle<'static, crate::state::Data>, handle: LoopHandle<'static, crate::state::State>,
) -> CosmicStack { ) -> CosmicStack {
let windows = windows.map(Into::into).collect::<Vec<_>>(); let windows = windows.map(Into::into).collect::<Vec<_>>();
assert!(!windows.is_empty()); assert!(!windows.is_empty());
@ -498,7 +497,7 @@ impl CosmicStack {
.with_program(|p| p.group_focused.store(true, Ordering::SeqCst)); .with_program(|p| p.group_focused.store(true, Ordering::SeqCst));
} }
pub(in super::super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { pub(in super::super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::State> {
self.0.loop_handle() self.0.loop_handle()
} }
@ -603,7 +602,7 @@ impl Program for CosmicStackInternal {
fn update( fn update(
&mut self, &mut self,
message: Self::Message, message: Self::Message,
loop_handle: &LoopHandle<'static, crate::state::Data>, loop_handle: &LoopHandle<'static, crate::state::State>,
) -> Command<Self::Message> { ) -> Command<Self::Message> {
match message { match message {
Message::DragStart => { Message::DragStart => {
@ -612,8 +611,8 @@ impl Program for CosmicStackInternal {
[self.active.load(Ordering::SeqCst)] [self.active.load(Ordering::SeqCst)]
.wl_surface() .wl_surface()
{ {
loop_handle.insert_idle(move |data| { loop_handle.insert_idle(move |state| {
Shell::move_request(&mut data.state, &surface, &seat, serial); Shell::move_request(state, &surface, &seat, serial);
}); });
} }
} }
@ -652,8 +651,10 @@ impl Program for CosmicStackInternal {
let group_focused = self.group_focused.load(Ordering::SeqCst); let group_focused = self.group_focused.load(Ordering::SeqCst);
let elements = vec![ let elements = vec![
cosmic_widget::icon("window-stack-symbolic", 16) cosmic_widget::icon::from_name("window-stack-symbolic")
.force_svg(true) .size(16)
.prefer_svg(true)
.icon()
.style(if group_focused { .style(if group_focused {
theme::Svg::custom(|theme| iced_widget::svg::Appearance { theme::Svg::custom(|theme| iced_widget::svg::Appearance {
color: Some(if theme.cosmic().is_dark { color: Some(if theme.cosmic().is_dark {
@ -663,7 +664,7 @@ impl Program for CosmicStackInternal {
}), }),
}) })
} else { } else {
theme::Svg::Symbolic theme::Svg::Default
}) })
.apply(iced_widget::container) .apply(iced_widget::container)
.padding([4, 24]) .padding([4, 24])
@ -712,6 +713,7 @@ impl Program for CosmicStackInternal {
.center_y() .center_y()
.style(if self.group_focused.load(Ordering::SeqCst) { .style(if self.group_focused.load(Ordering::SeqCst) {
theme::Container::custom(|theme| iced_widget::container::Appearance { theme::Container::custom(|theme| iced_widget::container::Appearance {
icon_color: Some(Color::from(theme.cosmic().background.on)),
text_color: Some(Color::from(theme.cosmic().background.on)), text_color: Some(Color::from(theme.cosmic().background.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())), background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: BorderRadius::from([8.0, 8.0, 0.0, 0.0]), border_radius: BorderRadius::from([8.0, 8.0, 0.0, 0.0]),
@ -720,6 +722,7 @@ impl Program for CosmicStackInternal {
}) })
} else { } else {
theme::Container::custom(|theme| iced_widget::container::Appearance { theme::Container::custom(|theme| iced_widget::container::Appearance {
icon_color: Some(Color::from(theme.cosmic().background.on)),
text_color: Some(Color::from(theme.cosmic().background.on)), text_color: Some(Color::from(theme.cosmic().background.on)),
background: Some(Background::Color(theme.cosmic().palette.neutral_3.into())), background: Some(Background::Color(theme.cosmic().palette.neutral_3.into())),
border_radius: BorderRadius::from([8.0, 8.0, 0.0, 0.0]), border_radius: BorderRadius::from([8.0, 8.0, 0.0, 0.0]),
@ -1080,9 +1083,9 @@ impl PointerTarget<State> for CosmicStack {
} }
let seat = seat.clone(); let seat = seat.clone();
data.common.event_loop_handle.insert_idle(move |data| { data.common.event_loop_handle.insert_idle(move |state| {
seat.get_pointer().unwrap().set_grab( seat.get_pointer().unwrap().set_grab(
&mut data.state, state,
grab, grab,
event.serial, event.serial,
smithay::input::pointer::Focus::Clear, smithay::input::pointer::Focus::Clear,

View file

@ -1,10 +1,7 @@
use apply::Apply;
use cosmic::{ use cosmic::{
font::Font, font::Font,
iced::{ iced::{
widget::{ widget::{self, container::draw_background, rule::FillMode},
self, container::draw_background, rule::FillMode, text::StyleSheet as TextStyleSheet,
},
Element, Element,
}, },
iced_core::{ iced_core::{
@ -13,6 +10,7 @@ use cosmic::{
mouse, overlay, renderer, mouse, overlay, renderer,
widget::{ widget::{
operation::{Operation, OperationOutputWrapper}, operation::{Operation, OperationOutputWrapper},
text::StyleSheet as TextStyleSheet,
tree::Tree, tree::Tree,
Id, Widget, Id, Widget,
}, },
@ -22,9 +20,10 @@ use cosmic::{
button::StyleSheet as ButtonStyleSheet, container::StyleSheet as ContainerStyleSheet, button::StyleSheet as ButtonStyleSheet, container::StyleSheet as ContainerStyleSheet,
rule::StyleSheet as RuleStyleSheet, rule::StyleSheet as RuleStyleSheet,
}, },
iced_widget::scrollable::AbsoluteOffset, iced_widget::{scrollable::AbsoluteOffset, text},
theme, theme,
widget::{icon, text, Icon}, widget::{icon::from_name, Icon},
Apply,
}; };
use super::tab_text::tab_text; use super::tab_text::tab_text;
@ -82,6 +81,7 @@ impl Into<theme::Container> for TabBackgroundTheme {
match self { match self {
Self::ActiveActivated => { Self::ActiveActivated => {
theme::Container::custom(move |theme| widget::container::Appearance { theme::Container::custom(move |theme| widget::container::Appearance {
icon_color: Some(Color::from(theme.cosmic().accent_text_color())),
text_color: Some(Color::from(theme.cosmic().accent_text_color())), text_color: Some(Color::from(theme.cosmic().accent_text_color())),
background: Some(background_color), background: Some(background_color),
border_radius: 0.0.into(), border_radius: 0.0.into(),
@ -91,6 +91,7 @@ impl Into<theme::Container> for TabBackgroundTheme {
} }
Self::ActiveDeactivated => { Self::ActiveDeactivated => {
theme::Container::custom(move |_theme| widget::container::Appearance { theme::Container::custom(move |_theme| widget::container::Appearance {
icon_color: None,
text_color: None, text_color: None,
background: Some(background_color), background: Some(background_color),
border_radius: 0.0.into(), border_radius: 0.0.into(),
@ -113,9 +114,9 @@ pub trait TabMessage: Clone {
fn scrolled() -> Self; fn scrolled() -> Self;
} }
pub struct Tab<'a, Message: TabMessage> { pub struct Tab<Message: TabMessage> {
id: Id, id: Id,
app_icon: Icon<'a>, app_icon: Icon,
title: String, title: String,
font: Font, font: Font,
close_message: Option<Message>, close_message: Option<Message>,
@ -125,11 +126,11 @@ pub struct Tab<'a, Message: TabMessage> {
active: bool, active: bool,
} }
impl<'a, Message: TabMessage> Tab<'a, Message> { impl<Message: TabMessage> Tab<Message> {
pub fn new(title: impl Into<String>, app_id: impl Into<String>, id: Id) -> Self { pub fn new(title: impl Into<String>, app_id: impl Into<String>, id: Id) -> Self {
Tab { Tab {
id, id,
app_icon: icon(app_id.into(), 16), app_icon: from_name(app_id.into()).size(16).icon(),
title: title.into(), title: title.into(),
font: cosmic::font::FONT, font: cosmic::font::FONT,
close_message: None, close_message: None,
@ -175,25 +176,27 @@ impl<'a, Message: TabMessage> Tab<'a, Message> {
self self
} }
pub(super) fn internal<Renderer>(self, idx: usize) -> TabInternal<'a, Message, Renderer> pub(super) fn internal<'a, Renderer>(self, idx: usize) -> TabInternal<'a, Message, Renderer>
where where
Renderer: cosmic::iced_core::Renderer + 'a, Renderer: cosmic::iced_core::Renderer + 'a,
Renderer: cosmic::iced_core::text::Renderer<Font = Font>, Renderer: cosmic::iced_core::text::Renderer<Font = Font>,
Renderer::Theme: ButtonStyleSheet<Style = theme::Button>, Renderer::Theme: ButtonStyleSheet<Style = theme::iced::Button>,
Renderer::Theme: ContainerStyleSheet, Renderer::Theme: ContainerStyleSheet,
Renderer::Theme: RuleStyleSheet<Style = theme::Rule>, Renderer::Theme: RuleStyleSheet<Style = theme::Rule>,
Renderer::Theme: TextStyleSheet, Renderer::Theme: TextStyleSheet,
Message: 'a, Message: 'a,
widget::Button<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>, widget::Button<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>,
widget::Container<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>, widget::Container<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>,
Icon<'a>: Into<Element<'a, Message, Renderer>>, widget::Text<'a, Renderer>: Into<Element<'a, Message, Renderer>>,
Icon: Into<Element<'a, Message, Renderer>>,
{ {
let mut close_button = icon("window-close-symbolic", 16) let mut close_button = from_name("window-close-symbolic")
.force_svg(true) .size(16)
.style(theme::Svg::Symbolic) .prefer_svg(true)
.icon()
.apply(widget::button) .apply(widget::button)
.padding(0) .padding(0)
.style(theme::Button::Text); .style(theme::iced::Button::Text);
if let Some(close_message) = self.close_message { if let Some(close_message) = self.close_message {
close_button = close_button.on_press(close_message); close_button = close_button.on_press(close_message);
} }
@ -207,16 +210,17 @@ impl<'a, Message: TabMessage> Tab<'a, Message> {
.padding([2, 4]) .padding([2, 4])
.center_y() .center_y()
.into(), .into(),
text(self.title) Element::<'a, Message, Renderer>::new(
.size(14) text(self.title)
.font(self.font) .size(14)
.horizontal_alignment(alignment::Horizontal::Left) .font(self.font)
.vertical_alignment(alignment::Vertical::Center) .horizontal_alignment(alignment::Horizontal::Left)
.apply(tab_text) .vertical_alignment(alignment::Vertical::Center)
.background(self.background_theme.background_color()) .apply(tab_text)
.height(Length::Fill) .background(self.background_theme.background_color())
.width(Length::Fill) .height(Length::Fill)
.into(), .width(Length::Fill),
),
close_button close_button
.apply(widget::container) .apply(widget::container)
.height(Length::Fill) .height(Length::Fill)
@ -325,7 +329,7 @@ where
renderer: &Renderer, renderer: &Renderer,
operation: &mut dyn Operation<OperationOutputWrapper<Message>>, operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
) { ) {
operation.container(None, &mut |operation| { operation.container(None, layout.bounds(), &mut |operation| {
self.elements self.elements
.iter() .iter()
.zip(&mut tree.children) .zip(&mut tree.children)
@ -347,6 +351,7 @@ where
renderer: &Renderer, renderer: &Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status { ) -> event::Status {
let status = self let status = self
.elements .elements
@ -362,6 +367,7 @@ where
renderer, renderer,
clipboard, clipboard,
shell, shell,
viewport,
) )
}) })
.fold(event::Status::Ignored, event::Status::merge); .fold(event::Status::Ignored, event::Status::merge);
@ -434,7 +440,9 @@ where
renderer, renderer,
theme, theme,
&renderer::Style { &renderer::Style {
icon_color: style.text_color.unwrap_or(renderer_style.text_color),
text_color: style.text_color.unwrap_or(renderer_style.text_color), text_color: style.text_color.unwrap_or(renderer_style.text_color),
scale_factor: renderer_style.scale_factor,
}, },
layout, layout,
cursor, cursor,

View file

@ -4,7 +4,7 @@ use cosmic::{
gradient, gradient,
layout::{Layout, Limits, Node}, layout::{Layout, Limits, Node},
mouse::Cursor, mouse::Cursor,
renderer, renderer::{self, Renderer as IcedRenderer},
widget::{Tree, Widget}, widget::{Tree, Widget},
Background, Color, Degrees, Gradient, Length, Point, Rectangle, Size, Background, Color, Degrees, Gradient, Length, Point, Rectangle, Size,
}, },
@ -13,7 +13,7 @@ use cosmic::{
pub struct TabText<'a, Message, Renderer> pub struct TabText<'a, Message, Renderer>
where where
Renderer: cosmic::iced_core::Renderer, Renderer: IcedRenderer,
Renderer::Theme: TextStyleSheet, Renderer::Theme: TextStyleSheet,
{ {
text: Element<'a, Message, Renderer>, text: Element<'a, Message, Renderer>,
@ -26,7 +26,7 @@ pub fn tab_text<'a, Message, Renderer>(
text: impl Into<Element<'a, Message, Renderer>>, text: impl Into<Element<'a, Message, Renderer>>,
) -> TabText<'a, Message, Renderer> ) -> TabText<'a, Message, Renderer>
where where
Renderer: cosmic::iced_core::Renderer, Renderer: IcedRenderer,
Renderer::Theme: TextStyleSheet, Renderer::Theme: TextStyleSheet,
{ {
TabText::new(text, Color::TRANSPARENT) TabText::new(text, Color::TRANSPARENT)
@ -34,7 +34,7 @@ where
impl<'a, Message, Renderer> TabText<'a, Message, Renderer> impl<'a, Message, Renderer> TabText<'a, Message, Renderer>
where where
Renderer: cosmic::iced_core::Renderer, Renderer: IcedRenderer,
Renderer::Theme: TextStyleSheet, Renderer::Theme: TextStyleSheet,
{ {
pub fn new(text: impl Into<Element<'a, Message, Renderer>>, background: Color) -> Self { pub fn new(text: impl Into<Element<'a, Message, Renderer>>, background: Color) -> Self {
@ -66,7 +66,7 @@ where
impl<'a, Message, Renderer> Widget<Message, Renderer> for TabText<'a, Message, Renderer> impl<'a, Message, Renderer> Widget<Message, Renderer> for TabText<'a, Message, Renderer>
where where
Renderer: cosmic::iced_core::Renderer, Renderer: IcedRenderer,
Renderer::Theme: TextStyleSheet, Renderer::Theme: TextStyleSheet,
{ {
fn width(&self) -> Length { fn width(&self) -> Length {
@ -148,7 +148,7 @@ where
impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>> for TabText<'a, Message, Renderer> impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>> for TabText<'a, Message, Renderer>
where where
Renderer: cosmic::iced_core::Renderer + 'a, Renderer: IcedRenderer + 'a,
Renderer::Theme: TextStyleSheet, Renderer::Theme: TextStyleSheet,
Message: 'a, Message: 'a,
{ {

View file

@ -1,5 +1,4 @@
use super::tab::{Tab, TabBackgroundTheme, TabMessage, TabRuleTheme, MIN_ACTIVE_TAB_WIDTH}; use super::tab::{Tab, TabBackgroundTheme, TabMessage, TabRuleTheme, MIN_ACTIVE_TAB_WIDTH};
use apply::Apply;
use cosmic::{ use cosmic::{
font::Font, font::Font,
iced::{id::Id, widget, Element}, iced::{id::Id, widget, Element},
@ -24,7 +23,8 @@ use cosmic::{
}, },
iced_widget::container::draw_background, iced_widget::container::draw_background,
theme, theme,
widget::{icon, Icon}, widget::{icon::from_name, Icon},
Apply,
}; };
use keyframe::{ use keyframe::{
ease, ease,
@ -122,17 +122,17 @@ impl<'a, Message, Renderer> Tabs<'a, Message, Renderer>
where where
Renderer: cosmic::iced_core::Renderer + 'a, Renderer: cosmic::iced_core::Renderer + 'a,
Renderer: cosmic::iced_core::text::Renderer<Font = Font>, Renderer: cosmic::iced_core::text::Renderer<Font = Font>,
Renderer::Theme: ButtonStyleSheet<Style = theme::Button>, Renderer::Theme: ButtonStyleSheet<Style = theme::iced::Button>,
Renderer::Theme: ContainerStyleSheet<Style = theme::Container>, Renderer::Theme: ContainerStyleSheet<Style = theme::Container>,
Renderer::Theme: RuleStyleSheet<Style = theme::Rule>, Renderer::Theme: RuleStyleSheet<Style = theme::Rule>,
Renderer::Theme: TextStyleSheet, Renderer::Theme: TextStyleSheet,
Message: TabMessage + 'a, Message: TabMessage + 'a,
widget::Button<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>, widget::Button<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>,
widget::Container<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>, widget::Container<'a, Message, Renderer>: Into<Element<'a, Message, Renderer>>,
Icon<'a>: Into<Element<'a, Message, Renderer>>, Icon: Into<Element<'a, Message, Renderer>>,
{ {
pub fn new( pub fn new(
tabs: impl IntoIterator<Item = Tab<'a, Message>>, tabs: impl IntoIterator<Item = Tab<Message>>,
active: usize, active: usize,
activated: bool, activated: bool,
group_focused: bool, group_focused: bool,
@ -189,22 +189,24 @@ where
TabRuleTheme::Default TabRuleTheme::Default
}) })
.into(), .into(),
icon("go-previous-symbolic", 16) from_name("go-previous-symbolic")
.force_svg(true) .size(16)
.style(theme::Svg::Symbolic) .prefer_svg(true)
.icon()
.apply(widget::button) .apply(widget::button)
.style(theme::Button::Text) .style(theme::iced::Button::Text)
.on_press(Message::scroll_back()) .on_press(Message::scroll_back())
.into(), .into(),
] ]
.into_iter() .into_iter()
.chain(tabs) .chain(tabs)
.chain(vec![ .chain(vec![
icon("go-next-symbolic", 16) from_name("go-next-symbolic")
.force_svg(true) .size(16)
.style(theme::Svg::Symbolic) .prefer_svg(true)
.icon()
.apply(widget::button) .apply(widget::button)
.style(theme::Button::Text) .style(theme::iced::Button::Text)
.on_press(Message::scroll_further()) .on_press(Message::scroll_further())
.into(), .into(),
widget::vertical_rule(4) widget::vertical_rule(4)
@ -489,6 +491,7 @@ where
let background_style = ContainerStyleSheet::appearance( let background_style = ContainerStyleSheet::appearance(
theme, theme,
&theme::Container::custom(|theme| widget::container::Appearance { &theme::Container::custom(|theme| widget::container::Appearance {
icon_color: None,
text_color: None, text_color: None,
background: Some(Background::Color(Color::from( background: Some(Background::Color(Color::from(
theme.cosmic().palette.neutral_3, theme.cosmic().palette.neutral_3,
@ -659,11 +662,18 @@ where
operation: &mut dyn Operation<OperationOutputWrapper<Message>>, operation: &mut dyn Operation<OperationOutputWrapper<Message>>,
) { ) {
let state = tree.state.downcast_mut::<State>(); let state = tree.state.downcast_mut::<State>();
let bounds = layout.bounds();
state.cleanup_old_animations(); state.cleanup_old_animations();
operation.scrollable(state, self.id.as_ref()); operation.scrollable(
state,
self.id.as_ref(),
bounds,
Vector { x: 0.0, y: 0.0 }, /* seemingly unused */
);
operation.container(self.id.as_ref(), &mut |operation| { operation.container(self.id.as_ref(), bounds, &mut |operation| {
self.elements[2..self.elements.len() - 3] self.elements[2..self.elements.len() - 3]
.iter() .iter()
.zip(tree.children.iter_mut().skip(2)) .zip(tree.children.iter_mut().skip(2))
@ -685,6 +695,7 @@ where
renderer: &Renderer, renderer: &Renderer,
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
viewport: &Rectangle,
) -> event::Status { ) -> event::Status {
let state = tree.state.downcast_mut::<State>(); let state = tree.state.downcast_mut::<State>();
state.cleanup_old_animations(); state.cleanup_old_animations();
@ -826,6 +837,7 @@ where
renderer, renderer,
clipboard, clipboard,
&mut internal_shell, &mut internal_shell,
viewport,
) )
}) })
.fold(event::Status::Ignored, event::Status::merge) .fold(event::Status::Ignored, event::Status::merge)
@ -848,6 +860,7 @@ where
renderer, renderer,
clipboard, clipboard,
&mut internal_shell, &mut internal_shell,
viewport,
) )
}) })
.fold(event::Status::Ignored, event::Status::merge) .fold(event::Status::Ignored, event::Status::merge)
@ -870,6 +883,7 @@ where
renderer, renderer,
clipboard, clipboard,
&mut internal_shell, &mut internal_shell,
viewport,
) )
}) })
.fold(event::Status::Ignored, event::Status::merge) .fold(event::Status::Ignored, event::Status::merge)

View file

@ -3,20 +3,20 @@ use crate::{
utils::iced::{IcedElement, Program}, utils::iced::{IcedElement, Program},
}; };
use apply::Apply;
use calloop::LoopHandle; use calloop::LoopHandle;
use cosmic::{ use cosmic::{
iced::widget::{container, row}, iced::widget::{container, row},
iced_core::{Background, Color, Length}, iced_core::{Background, Color, Length},
theme, theme,
widget::{icon, text}, widget::{icon::from_name, text},
Apply,
}; };
use smithay::utils::{Logical, Size}; use smithay::utils::{Logical, Size};
pub type StackHover = IcedElement<StackHoverInternal>; pub type StackHover = IcedElement<StackHoverInternal>;
pub fn stack_hover( pub fn stack_hover(
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
size: Size<i32, Logical>, size: Size<i32, Logical>,
) -> StackHover { ) -> StackHover {
StackHover::new(StackHoverInternal, size, evlh) StackHover::new(StackHoverInternal, size, evlh)
@ -29,8 +29,10 @@ impl Program for StackHoverInternal {
fn view(&self) -> crate::utils::iced::Element<'_, Self::Message> { fn view(&self) -> crate::utils::iced::Element<'_, Self::Message> {
row(vec![ row(vec![
icon("window-stack-symbolic", 24) from_name("window-stack-symbolic")
.force_svg(true) .size(24)
.prefer_svg(true)
.icon()
.apply(container) .apply(container)
.padding([0, 8, 0, 0]) .padding([0, 8, 0, 0])
.width(Length::Shrink) .width(Length::Shrink)
@ -54,6 +56,7 @@ impl Program for StackHoverInternal {
.apply(container) .apply(container)
.padding([8, 16]) .padding([8, 16])
.style(theme::Container::custom(|theme| container::Appearance { .style(theme::Container::custom(|theme| container::Appearance {
icon_color: Some(Color::from(theme.cosmic().accent.on)),
text_color: Some(Color::from(theme.cosmic().accent.on)), text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())), background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 24.0.into(), border_radius: 24.0.into(),

View file

@ -3,19 +3,19 @@ use crate::{
utils::iced::{IcedElement, Program}, utils::iced::{IcedElement, Program},
}; };
use apply::Apply;
use calloop::LoopHandle; use calloop::LoopHandle;
use cosmic::{ use cosmic::{
iced::widget::{container, horizontal_space, row}, iced::widget::{container, horizontal_space, row},
iced_core::{Alignment, Background, Color, Length}, iced_core::{Alignment, Background, Color, Length},
theme, theme,
widget::{icon, text}, widget::{icon::from_name, text},
Apply,
}; };
use smithay::utils::Size; use smithay::utils::Size;
pub type SwapIndicator = IcedElement<SwapIndicatorInternal>; pub type SwapIndicator = IcedElement<SwapIndicatorInternal>;
pub fn swap_indicator(evlh: LoopHandle<'static, crate::state::Data>) -> SwapIndicator { pub fn swap_indicator(evlh: LoopHandle<'static, crate::state::State>) -> SwapIndicator {
SwapIndicator::new(SwapIndicatorInternal, Size::from((1, 1)), evlh) SwapIndicator::new(SwapIndicatorInternal, Size::from((1, 1)), evlh)
} }
@ -26,7 +26,11 @@ impl Program for SwapIndicatorInternal {
fn view(&self) -> crate::utils::iced::Element<'_, Self::Message> { fn view(&self) -> crate::utils::iced::Element<'_, Self::Message> {
row(vec![ row(vec![
icon("window-swap-symbolic", 32).force_svg(true).into(), from_name("window-swap-symbolic")
.size(32)
.prefer_svg(true)
.icon()
.into(),
horizontal_space(16).into(), horizontal_space(16).into(),
text(fl!("swap-windows")) text(fl!("swap-windows"))
.font(cosmic::font::FONT) .font(cosmic::font::FONT)
@ -40,6 +44,7 @@ impl Program for SwapIndicatorInternal {
.padding(16) .padding(16)
.apply(container) .apply(container)
.style(theme::Container::custom(|theme| container::Appearance { .style(theme::Container::custom(|theme| container::Appearance {
icon_color: Some(Color::from(theme.cosmic().accent.on)),
text_color: Some(Color::from(theme.cosmic().accent.on)), text_color: Some(Color::from(theme.cosmic().accent.on)),
background: Some(Background::Color(theme.cosmic().accent_color().into())), background: Some(Background::Color(theme.cosmic().accent_color().into())),
border_radius: 18.0.into(), border_radius: 18.0.into(),

View file

@ -113,7 +113,7 @@ impl CosmicWindowInternal {
impl CosmicWindow { impl CosmicWindow {
pub fn new( pub fn new(
window: impl Into<CosmicSurface>, window: impl Into<CosmicSurface>,
handle: LoopHandle<'static, crate::state::Data>, handle: LoopHandle<'static, crate::state::State>,
) -> CosmicWindow { ) -> CosmicWindow {
let window = window.into(); let window = window.into();
let width = window.geometry().size.w; let width = window.geometry().size.w;
@ -166,7 +166,7 @@ impl CosmicWindow {
} }
} }
pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { pub(super) fn loop_handle(&self) -> LoopHandle<'static, crate::state::State> {
self.0.loop_handle() self.0.loop_handle()
} }
@ -228,14 +228,14 @@ impl Program for CosmicWindowInternal {
fn update( fn update(
&mut self, &mut self,
message: Self::Message, message: Self::Message,
loop_handle: &LoopHandle<'static, crate::state::Data>, loop_handle: &LoopHandle<'static, crate::state::State>,
) -> Command<Self::Message> { ) -> Command<Self::Message> {
match message { match message {
Message::DragStart => { Message::DragStart => {
if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() { if let Some((seat, serial)) = self.last_seat.lock().unwrap().clone() {
if let Some(surface) = self.window.wl_surface() { if let Some(surface) = self.window.wl_surface() {
loop_handle.insert_idle(move |data| { loop_handle.insert_idle(move |state| {
Shell::move_request(&mut data.state, &surface, &seat, serial); Shell::move_request(state, &surface, &seat, serial);
}); });
} }
} }
@ -243,17 +243,11 @@ impl Program for CosmicWindowInternal {
Message::Maximize => { Message::Maximize => {
if let Some((seat, _serial)) = self.last_seat.lock().unwrap().clone() { if let Some((seat, _serial)) = self.last_seat.lock().unwrap().clone() {
if let Some(surface) = self.window.wl_surface() { if let Some(surface) = self.window.wl_surface() {
loop_handle.insert_idle(move |data| { loop_handle.insert_idle(move |state| {
if let Some(mapped) = data if let Some(mapped) =
.state state.common.shell.element_for_wl_surface(&surface).cloned()
.common
.shell
.element_for_wl_surface(&surface)
.cloned()
{ {
if let Some(workspace) = if let Some(workspace) = state.common.shell.space_for_mut(&mapped) {
data.state.common.shell.space_for_mut(&mapped)
{
let output = seat.active_output(); let output = seat.active_output();
let (window, _) = mapped let (window, _) = mapped
.windows() .windows()
@ -262,7 +256,7 @@ impl Program for CosmicWindowInternal {
workspace.maximize_toggle( workspace.maximize_toggle(
&window, &window,
&output, &output,
data.state.common.event_loop_handle.clone(), state.common.event_loop_handle.clone(),
) )
} }
} }

View file

@ -21,17 +21,18 @@ mod moving;
pub use self::moving::*; pub use self::moving::*;
bitflags::bitflags! { bitflags::bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ResizeEdge: u32 { pub struct ResizeEdge: u32 {
const TOP = 0b0001; const TOP = 0b0001;
const BOTTOM = 0b0010; const BOTTOM = 0b0010;
const LEFT = 0b0100; const LEFT = 0b0100;
const RIGHT = 0b1000; const RIGHT = 0b1000;
const TOP_LEFT = Self::TOP.bits | Self::LEFT.bits; const TOP_LEFT = Self::TOP.bits() | Self::LEFT.bits();
const BOTTOM_LEFT = Self::BOTTOM.bits | Self::LEFT.bits; const BOTTOM_LEFT = Self::BOTTOM.bits() | Self::LEFT.bits();
const TOP_RIGHT = Self::TOP.bits | Self::RIGHT.bits; const TOP_RIGHT = Self::TOP.bits() | Self::RIGHT.bits();
const BOTTOM_RIGHT = Self::BOTTOM.bits | Self::RIGHT.bits; const BOTTOM_RIGHT = Self::BOTTOM.bits() | Self::RIGHT.bits();
} }
} }

View file

@ -366,6 +366,7 @@ impl FloatingLayout {
KeyboardFocusTarget::Popup(popup) => { KeyboardFocusTarget::Popup(popup) => {
let Some(toplevel_surface) = (match popup { let Some(toplevel_surface) = (match popup {
PopupKind::Xdg(xdg) => get_popup_toplevel(&xdg), PopupKind::Xdg(xdg) => get_popup_toplevel(&xdg),
PopupKind::InputMethod(_) => unreachable!(),
}) else { }) else {
return FocusResult::None return FocusResult::None
}; };
@ -436,6 +437,7 @@ impl FloatingLayout {
KeyboardFocusTarget::Popup(popup) => { KeyboardFocusTarget::Popup(popup) => {
let Some(toplevel_surface) = (match popup { let Some(toplevel_surface) = (match popup {
PopupKind::Xdg(xdg) => get_popup_toplevel(&xdg), PopupKind::Xdg(xdg) => get_popup_toplevel(&xdg),
PopupKind::InputMethod(_) => unreachable!(),
}) else { }) else {
return MoveResult::None return MoveResult::None
}; };

View file

@ -69,11 +69,11 @@ impl PointerTarget<State> for ResizeForkTarget {
let orientation = self.orientation; let orientation = self.orientation;
let serial = event.serial; let serial = event.serial;
let button = event.button; let button = event.button;
data.common.event_loop_handle.insert_idle(move |data| { data.common.event_loop_handle.insert_idle(move |state| {
let pointer = seat.get_pointer().unwrap(); let pointer = seat.get_pointer().unwrap();
let location = pointer.current_location(); let location = pointer.current_location();
pointer.set_grab( pointer.set_grab(
&mut data.state, state,
ResizeForkGrab { ResizeForkGrab {
start_data: PointerGrabStartData { start_data: PointerGrabStartData {
focus: None, focus: None,

View file

@ -9,6 +9,7 @@ use smithay::{
}, },
utils::Serial, utils::Serial,
}; };
use xkbcommon::xkb::Keysym;
use crate::{ use crate::{
config::{Action, KeyPattern}, config::{Action, KeyPattern},
@ -71,7 +72,7 @@ impl KeyboardGrab<State> for SwapWindowGrab {
time, time,
KeyPattern { KeyPattern {
modifiers: modifiers.map(Into::into).unwrap_or_default(), modifiers: modifiers.map(Into::into).unwrap_or_default(),
key: Some(keycode), key: Some(Keysym::new(keycode)),
}, },
None, None,
); );

View file

@ -2660,6 +2660,7 @@ impl TilingLayout {
if let KeyboardFocusTarget::Popup(popup) = target { if let KeyboardFocusTarget::Popup(popup) = target {
let toplevel_surface = match popup { let toplevel_surface = match popup {
PopupKind::Xdg(xdg) => get_popup_toplevel(&xdg), PopupKind::Xdg(xdg) => get_popup_toplevel(&xdg),
PopupKind::InputMethod(_) => unreachable!(),
}?; }?;
let root_id = tree.root_node_id()?; let root_id = tree.root_node_id()?;
let node = let node =

View file

@ -1219,7 +1219,7 @@ impl Shell {
pub fn set_overview_mode( pub fn set_overview_mode(
&mut self, &mut self,
enabled: Option<Trigger>, enabled: Option<Trigger>,
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
) { ) {
if let Some(trigger) = enabled { if let Some(trigger) = enabled {
if !matches!(self.overview_mode, OverviewMode::Started(_, _)) { if !matches!(self.overview_mode, OverviewMode::Started(_, _)) {
@ -1261,7 +1261,7 @@ impl Shell {
&mut self, &mut self,
enabled: Option<(KeyPattern, ResizeDirection)>, enabled: Option<(KeyPattern, ResizeDirection)>,
config: &Config, config: &Config,
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
) { ) {
if let Some((pattern, direction)) = enabled { if let Some((pattern, direction)) = enabled {
if let ResizeMode::Started(old_pattern, _, old_direction) = &mut self.resize_mode { if let ResizeMode::Started(old_pattern, _, old_direction) = &mut self.resize_mode {

View file

@ -430,7 +430,7 @@ impl Workspace {
&mut self, &mut self,
window: &CosmicSurface, window: &CosmicSurface,
output: &Output, output: &Output,
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
) { ) {
if self.fullscreen.contains_key(output) { if self.fullscreen.contains_key(output) {
return; return;
@ -459,7 +459,7 @@ impl Workspace {
&mut self, &mut self,
window: &CosmicSurface, window: &CosmicSurface,
output: &Output, output: &Output,
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
) { ) {
if self if self
.fullscreen .fullscreen
@ -484,7 +484,7 @@ impl Workspace {
window: &'a CosmicSurface, window: &'a CosmicSurface,
output: &Output, output: &Output,
exclusive: bool, exclusive: bool,
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
) { ) {
if let Some(mapped) = self if let Some(mapped) = self
.mapped() .mapped()
@ -635,7 +635,7 @@ impl Workspace {
&mut self, &mut self,
window: &CosmicSurface, window: &CosmicSurface,
output: &Output, output: &Output,
evlh: LoopHandle<'static, crate::state::Data>, evlh: LoopHandle<'static, crate::state::State>,
) { ) {
if self.fullscreen.contains_key(output) { if self.fullscreen.contains_key(output) {
self.unmaximize_request(window); self.unmaximize_request(window);

View file

@ -54,7 +54,7 @@ use smithay::{
wayland_server::{ wayland_server::{
backend::{ClientData, ClientId, DisconnectReason}, backend::{ClientData, ClientId, DisconnectReason},
protocol::wl_shm, protocol::wl_shm,
Client, Display, DisplayHandle, Client, DisplayHandle,
}, },
}, },
utils::{Clock, IsAlive, Monotonic}, utils::{Clock, IsAlive, Monotonic},
@ -114,11 +114,6 @@ impl ClientData for ClientState {
} }
} }
pub struct Data {
pub display: Display<State>,
pub state: State,
}
#[derive(Debug)] #[derive(Debug)]
pub struct State { pub struct State {
pub backend: BackendData, pub backend: BackendData,
@ -131,7 +126,7 @@ pub struct Common {
pub socket: OsString, pub socket: OsString,
pub display_handle: DisplayHandle, pub display_handle: DisplayHandle,
pub event_loop_handle: LoopHandle<'static, Data>, pub event_loop_handle: LoopHandle<'static, State>,
pub event_loop_signal: LoopSignal, pub event_loop_signal: LoopSignal,
//pub output_conf: ConfigurationManager, //pub output_conf: ConfigurationManager,
@ -212,7 +207,7 @@ impl BackendData {
test_only: bool, test_only: bool,
shell: &mut Shell, shell: &mut Shell,
seats: impl Iterator<Item = Seat<State>>, seats: impl Iterator<Item = Seat<State>>,
loop_handle: &LoopHandle<'_, Data>, loop_handle: &LoopHandle<'_, State>,
) -> Result<(), anyhow::Error> { ) -> Result<(), anyhow::Error> {
let result = match self { let result = match self {
BackendData::Kms(ref mut state) => { BackendData::Kms(ref mut state) => {
@ -252,7 +247,7 @@ impl BackendData {
pub fn schedule_render( pub fn schedule_render(
&mut self, &mut self,
loop_handle: &LoopHandle<'_, Data>, loop_handle: &LoopHandle<'_, State>,
output: &Output, output: &Output,
screencopy: Option<Vec<(ScreencopySession, BufferParams)>>, screencopy: Option<Vec<(ScreencopySession, BufferParams)>>,
) { ) {
@ -281,7 +276,7 @@ impl State {
pub fn new( pub fn new(
dh: &DisplayHandle, dh: &DisplayHandle,
socket: OsString, socket: OsString,
handle: LoopHandle<'static, Data>, handle: LoopHandle<'static, State>,
signal: LoopSignal, signal: LoopSignal,
) -> State { ) -> State {
let requested_languages = DesktopLanguageRequester::requested_languages(); let requested_languages = DesktopLanguageRequester::requested_languages();

View file

@ -15,19 +15,19 @@ use cosmic::{
Command, Point as IcedPoint, Rectangle as IcedRectangle, Size as IcedSize, Command, Point as IcedPoint, Rectangle as IcedRectangle, Size as IcedSize,
}, },
iced_core::{clipboard::Null as NullClipboard, renderer::Style, Color}, iced_core::{clipboard::Null as NullClipboard, renderer::Style, Color},
iced_renderer::Backend as BackendWrapper, iced_renderer::{graphics::Renderer as IcedGraphicsRenderer, Renderer as IcedRenderer},
iced_runtime::{ iced_runtime::{
command::Action, command::Action,
program::{Program as IcedProgram, State}, program::{Program as IcedProgram, State},
Debug, Debug,
}, },
Renderer as IcedRenderer, Theme, Theme,
}; };
use iced_tiny_skia::{ use iced_tiny_skia::{
graphics::{damage, Primitive, Viewport}, graphics::{damage, Viewport},
Backend, Backend, Primitive,
}; };
pub type Element<'a, Message> = cosmic::iced::Element<'a, Message, IcedRenderer>; pub type Element<'a, Message> = cosmic::iced::Element<'a, Message, IcedRenderer<Theme>>;
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use smithay::{ use smithay::{
@ -98,7 +98,7 @@ pub trait Program {
fn update( fn update(
&mut self, &mut self,
message: Self::Message, message: Self::Message,
loop_handle: &LoopHandle<'static, crate::state::Data>, loop_handle: &LoopHandle<'static, crate::state::State>,
) -> Command<Self::Message> { ) -> Command<Self::Message> {
let _ = (message, loop_handle); let _ = (message, loop_handle);
Command::none() Command::none()
@ -119,10 +119,10 @@ pub trait Program {
} }
} }
struct ProgramWrapper<P: Program>(P, LoopHandle<'static, crate::state::Data>); struct ProgramWrapper<P: Program>(P, LoopHandle<'static, crate::state::State>);
impl<P: Program> IcedProgram for ProgramWrapper<P> { impl<P: Program> IcedProgram for ProgramWrapper<P> {
type Message = <P as Program>::Message; type Message = <P as Program>::Message;
type Renderer = IcedRenderer; type Renderer = IcedRenderer<Theme>;
fn update(&mut self, message: Self::Message) -> Command<Self::Message> { fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
self.0.update(message, &self.1) self.0.update(message, &self.1)
@ -145,12 +145,12 @@ struct IcedElementInternal<P: Program + Send + 'static> {
// iced // iced
theme: Theme, theme: Theme,
renderer: IcedRenderer, renderer: IcedRenderer<Theme>,
state: State<ProgramWrapper<P>>, state: State<ProgramWrapper<P>>,
debug: Debug, debug: Debug,
// futures // futures
handle: LoopHandle<'static, crate::state::Data>, handle: LoopHandle<'static, crate::state::State>,
scheduler: Scheduler<<P as Program>::Message>, scheduler: Scheduler<<P as Program>::Message>,
executor_token: Option<RegistrationToken>, executor_token: Option<RegistrationToken>,
rx: Receiver<<P as Program>::Message>, rx: Receiver<<P as Program>::Message>,
@ -171,7 +171,7 @@ impl<P: Program + Send + Clone + 'static> Clone for IcedElementInternal<P> {
tracing::warn!("Missing force_update call"); tracing::warn!("Missing force_update call");
} }
let mut renderer = let mut renderer =
IcedRenderer::new(BackendWrapper::TinySkia(Backend::new(Default::default()))); IcedRenderer::TinySkia(IcedGraphicsRenderer::new(Backend::new(Default::default())));
let mut debug = Debug::new(); let mut debug = Debug::new();
let state = State::new( let state = State::new(
Id(0), Id(0),
@ -228,11 +228,11 @@ impl<P: Program + Send + 'static> IcedElement<P> {
pub fn new( pub fn new(
program: P, program: P,
size: impl Into<Size<i32, Logical>>, size: impl Into<Size<i32, Logical>>,
handle: LoopHandle<'static, crate::state::Data>, handle: LoopHandle<'static, crate::state::State>,
) -> IcedElement<P> { ) -> IcedElement<P> {
let size = size.into(); let size = size.into();
let mut renderer = let mut renderer =
IcedRenderer::new(BackendWrapper::TinySkia(Backend::new(Default::default()))); IcedRenderer::TinySkia(IcedGraphicsRenderer::new(Backend::new(Default::default())));
let mut debug = Debug::new(); let mut debug = Debug::new();
let state = State::new( let state = State::new(
@ -276,7 +276,7 @@ impl<P: Program + Send + 'static> IcedElement<P> {
func(&internal.state.program().0) func(&internal.state.program().0)
} }
pub fn loop_handle(&self) -> LoopHandle<'static, crate::state::Data> { pub fn loop_handle(&self) -> LoopHandle<'static, crate::state::State> {
self.0.lock().unwrap().handle.clone() self.0.lock().unwrap().handle.clone()
} }
@ -353,6 +353,8 @@ impl<P: Program + Send + 'static> IcedElementInternal<P> {
&mut self.renderer, &mut self.renderer,
&self.theme, &self.theme,
&Style { &Style {
scale_factor: 1.0, //TODO: why is this
icon_color: self.theme.cosmic().on_bg_color().into(),
text_color: self.theme.cosmic().on_bg_color().into(), text_color: self.theme.cosmic().on_bg_color().into(),
}, },
&mut NullClipboard, &mut NullClipboard,
@ -738,7 +740,7 @@ where
.to_i32_round(); .to_i32_round();
if size.w > 0 && size.h > 0 { if size.w > 0 && size.h > 0 {
let renderer = &mut internal_ref.renderer; let IcedRenderer::TinySkia(renderer) = &mut internal_ref.renderer;
let state_ref = &internal_ref.state; let state_ref = &internal_ref.state;
let mut clip_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap(); let mut clip_mask = tiny_skia::Mask::new(size.w as u32, size.h as u32).unwrap();
let overlay = internal_ref.debug.overlay(); let overlay = internal_ref.debug.overlay();
@ -751,7 +753,6 @@ where
.expect("Failed to create pixel map"); .expect("Failed to create pixel map");
renderer.with_primitives(|backend, primitives| { renderer.with_primitives(|backend, primitives| {
let BackendWrapper::TinySkia(ref mut backend) = backend;
let background_color = state_ref.program().0.background_color(); let background_color = state_ref.program().0.background_color();
let bounds = IcedSize::new(size.w as u32, size.h as u32); let bounds = IcedSize::new(size.w as u32, size.h as u32);
let viewport = Viewport::with_physical_size(bounds, scale.x); let viewport = Viewport::with_physical_size(bounds, scale.x);

View file

@ -2,7 +2,7 @@
use crate::{ use crate::{
shell::CosmicSurface, shell::CosmicSurface,
state::{BackendData, ClientState, Data}, state::{BackendData, ClientState},
utils::prelude::*, utils::prelude::*,
wayland::protocols::screencopy::SessionType, wayland::protocols::screencopy::SessionType,
}; };
@ -73,20 +73,21 @@ impl State {
} }
fn xdg_popup_ensure_initial_configure(&mut self, popup: &PopupKind) { fn xdg_popup_ensure_initial_configure(&mut self, popup: &PopupKind) {
let PopupKind::Xdg(ref popup) = popup; if let PopupKind::Xdg(ref popup) = popup {
let initial_configure_sent = with_states(popup.wl_surface(), |states| { let initial_configure_sent = with_states(popup.wl_surface(), |states| {
states states
.data_map .data_map
.get::<Mutex<XdgPopupSurfaceRoleAttributes>>() .get::<Mutex<XdgPopupSurfaceRoleAttributes>>()
.unwrap() .unwrap()
.lock() .lock()
.unwrap() .unwrap()
.initial_configure_sent .initial_configure_sent
}); });
if !initial_configure_sent { if !initial_configure_sent {
// NOTE: This should never fail as the initial configure is always // NOTE: This should never fail as the initial configure is always
// allowed. // allowed.
popup.send_configure().expect("initial configure failed"); popup.send_configure().expect("initial configure failed");
}
} }
} }
@ -149,10 +150,11 @@ impl CompositorHandler for State {
state state
.common .common
.event_loop_handle .event_loop_handle
.insert_source(source, move |_, _, data| { .insert_source(source, move |_, _, state| {
data.state let dh = state.common.display_handle.clone();
state
.client_compositor_state(&client) .client_compositor_state(&client)
.blocker_cleared(&mut data.state, &data.display.handle()); .blocker_cleared(state, &dh);
Ok(()) Ok(())
}); });
if res.is_ok() { if res.is_ok() {
@ -164,7 +166,7 @@ impl CompositorHandler for State {
} }
fn commit(&mut self, surface: &WlSurface) { fn commit(&mut self, surface: &WlSurface) {
X11Wm::commit_hook::<Data>(surface); X11Wm::commit_hook::<State>(surface);
// first load the buffer for various smithay helper functions // first load the buffer for various smithay helper functions
on_commit_buffer_handler::<Self>(surface); on_commit_buffer_handler::<Self>(surface);

View file

@ -137,8 +137,8 @@ impl State {
self.common self.common
.config .config
.write_outputs(self.common.output_configuration_state.outputs()); .write_outputs(self.common.output_configuration_state.outputs());
self.common.event_loop_handle.insert_idle(move |data| { self.common.event_loop_handle.insert_idle(move |state| {
data.state.common.output_configuration_state.update(); state.common.output_configuration_state.update();
}); });
true true

View file

@ -46,7 +46,7 @@ use crate::{
render_output, render_workspace, CursorMode, CLEAR_COLOR, render_output, render_workspace, CursorMode, CLEAR_COLOR,
}, },
shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement}, shell::{CosmicMappedRenderElement, CosmicSurface, WorkspaceRenderElement},
state::{BackendData, ClientState, Common, Data, State}, state::{BackendData, ClientState, Common, State},
utils::prelude::OutputExt, utils::prelude::OutputExt,
wayland::protocols::{ wayland::protocols::{
screencopy::{ screencopy::{
@ -1173,19 +1173,14 @@ impl State {
if active.wl_surface().as_ref() == Some(surface) { if active.wl_surface().as_ref() == Some(surface) {
for (session, params) in active.pending_buffers() { for (session, params) in active.pending_buffers() {
let window = active.clone(); let window = active.clone();
self.common.event_loop_handle.insert_idle(move |data| { self.common.event_loop_handle.insert_idle(move |state| {
if !session.alive() { if !session.alive() {
return; return;
} }
match render_window_to_buffer( match render_window_to_buffer(state, &session, params.clone(), &window) {
&mut data.state,
&session,
params.clone(),
&window,
) {
// rendering yielded no damage, buffer is still pending // rendering yielded no damage, buffer is still pending
Ok(false) => data.state.common.still_pending(session, params), Ok(false) => state.common.still_pending(session, params),
Ok(true) => {} // success Ok(true) => {} // success
Err((reason, err)) => { Err((reason, err)) => {
warn!(?err, "Screencopy session failed"); warn!(?err, "Screencopy session failed");
@ -1291,21 +1286,21 @@ impl State {
} }
pub fn schedule_offscreen_workspace_session( pub fn schedule_offscreen_workspace_session(
event_loop_handle: &LoopHandle<'static, Data>, event_loop_handle: &LoopHandle<'static, State>,
session: Session, session: Session,
params: BufferParams, params: BufferParams,
output: Output, output: Output,
handle: WorkspaceHandle, handle: WorkspaceHandle,
) { ) {
event_loop_handle.insert_idle(move |data| { event_loop_handle.insert_idle(move |state| {
if !session.alive() { if !session.alive() {
return; return;
} }
if !data.state.common.shell.outputs.contains(&output) { if !state.common.shell.outputs.contains(&output) {
return; return;
} }
match render_workspace_to_buffer( match render_workspace_to_buffer(
&mut data.state, state,
&session, &session,
params.clone(), params.clone(),
&output, &output,
@ -1313,7 +1308,7 @@ pub fn schedule_offscreen_workspace_session(
) { ) {
Ok(false) => { Ok(false) => {
// rendering yielded no new damage, buffer still pending // rendering yielded no new damage, buffer still pending
data.state.common.still_pending(session, params); state.common.still_pending(session, params);
} }
Ok(true) => {} Ok(true) => {}
Err((reason, err)) => { Err((reason, err)) => {

View file

@ -16,12 +16,12 @@ impl SecurityContextHandler for State {
) { ) {
self.common self.common
.event_loop_handle .event_loop_handle
.insert_source(source, move |client_stream, _, data| { .insert_source(source, move |client_stream, _, state| {
if let Err(err) = data.display.handle().insert_client( if let Err(err) = state.common.display_handle.insert_client(
client_stream, client_stream,
Arc::new(ClientState { Arc::new(ClientState {
security_context: Some(security_context.clone()), security_context: Some(security_context.clone()),
..data.state.new_client_state() ..state.new_client_state()
}), }),
) { ) {
warn!(?err, "Error adding wayland client"); warn!(?err, "Error adding wayland client");

View file

@ -95,6 +95,7 @@ pub fn update_reactive_popups<'a>(
} }
} }
} }
PopupKind::InputMethod(_) => {}
} }
} }
} }

View file

@ -11,7 +11,7 @@ use smithay::{
zwlr_output_mode_v1::{self, ZwlrOutputModeV1}, zwlr_output_mode_v1::{self, ZwlrOutputModeV1},
}, },
wayland_server::{ wayland_server::{
backend::{ClientId, GlobalId, ObjectId}, backend::{ClientId, GlobalId},
protocol::wl_output::WlOutput, protocol::wl_output::WlOutput,
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
}, },
@ -247,9 +247,9 @@ where
} }
} }
fn destroyed(state: &mut D, _client: ClientId, resource: ObjectId, _data: &Output) { fn destroyed(state: &mut D, _client: ClientId, resource: &ZwlrOutputHeadV1, _data: &Output) {
for instance in &mut state.output_configuration_state().instances { for instance in &mut state.output_configuration_state().instances {
instance.heads.retain(|h| h.head.id() != resource); instance.heads.retain(|h| &h.head != resource);
} }
} }
} }

View file

@ -883,18 +883,18 @@ where
fn destroyed( fn destroyed(
state: &mut D, state: &mut D,
_client: wayland_backend::server::ClientId, _client: wayland_backend::server::ClientId,
resource: wayland_backend::server::ObjectId, resource: &ZcosmicScreencopySessionV1,
data: &SessionData, data: &SessionData,
) { ) {
if data.inner.lock().unwrap().is_cursor() { if data.inner.lock().unwrap().is_cursor() {
let session = CursorSession { let session = CursorSession {
obj: SessionResource::Destroyed(resource), obj: SessionResource::Destroyed(resource.id()),
data: data.clone(), data: data.clone(),
}; };
state.cursor_session_destroyed(session) state.cursor_session_destroyed(session)
} else { } else {
let session = Session { let session = Session {
obj: SessionResource::Destroyed(resource), obj: SessionResource::Destroyed(resource.id()),
data: data.clone(), data: data.clone(),
}; };
state.session_destroyed(session) state.session_destroyed(session)

View file

@ -5,7 +5,7 @@ use std::{collections::HashMap, sync::Mutex};
use smithay::{ use smithay::{
output::Output, output::Output,
reexports::wayland_server::{ reexports::wayland_server::{
backend::{ClientId, GlobalId, ObjectId}, backend::{ClientId, GlobalId},
protocol::wl_surface::WlSurface, protocol::wl_surface::WlSurface,
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
}, },
@ -139,11 +139,11 @@ where
} }
} }
fn destroyed(state: &mut D, _client: ClientId, resource: ObjectId, _data: &()) { fn destroyed(state: &mut D, _client: ClientId, resource: &ZcosmicToplevelInfoV1, _data: &()) {
state state
.toplevel_info_state_mut() .toplevel_info_state_mut()
.instances .instances
.retain(|i| i.id() != resource); .retain(|i| i != resource);
} }
} }
@ -174,16 +174,12 @@ where
fn destroyed( fn destroyed(
state: &mut D, state: &mut D,
_client: ClientId, _client: ClientId,
resource: ObjectId, resource: &ZcosmicToplevelHandleV1,
_data: &ToplevelHandleState<W>, _data: &ToplevelHandleState<W>,
) { ) {
for toplevel in &state.toplevel_info_state_mut().toplevels { for toplevel in &state.toplevel_info_state_mut().toplevels {
if let Some(state) = toplevel.user_data().get::<ToplevelState>() { if let Some(state) = toplevel.user_data().get::<ToplevelState>() {
state state.lock().unwrap().instances.retain(|i| i != resource);
.lock()
.unwrap()
.instances
.retain(|i| i.id() != resource);
} }
} }
} }

View file

@ -4,7 +4,7 @@ use smithay::{
input::{Seat, SeatHandler}, input::{Seat, SeatHandler},
output::Output, output::Output,
reexports::wayland_server::{ reexports::wayland_server::{
backend::{ClientId, GlobalId, ObjectId}, backend::{ClientId, GlobalId},
protocol::wl_surface::WlSurface, protocol::wl_surface::WlSurface,
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource, Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
}, },
@ -225,9 +225,9 @@ where
} }
} }
fn destroyed(state: &mut D, client: ClientId, resource: ObjectId, _data: &()) { fn destroyed(state: &mut D, client: ClientId, resource: &ZcosmicToplevelManagerV1, _data: &()) {
let mng_state = state.toplevel_management_state(); let mng_state = state.toplevel_management_state();
mng_state.instances.retain(|i| i.id() != resource); mng_state.instances.retain(|i| i != resource);
if !mng_state if !mng_state
.instances .instances
.iter() .iter()

View file

@ -211,11 +211,16 @@ where
} }
} }
fn destroyed(state: &mut D, _client: ClientId, resource: ObjectId, _data: &()) { fn destroyed(
state: &mut D,
_client: ClientId,
resource: &ZcosmicWorkspaceManagerV1,
_data: &(),
) {
state state
.workspace_state_mut() .workspace_state_mut()
.instances .instances
.retain(|i| i.id() != resource); .retain(|i| i != resource);
} }
} }
@ -268,9 +273,14 @@ where
} }
} }
fn destroyed(state: &mut D, _client: ClientId, resource: ObjectId, _data: &WorkspaceGroupData) { fn destroyed(
state: &mut D,
_client: ClientId,
resource: &ZcosmicWorkspaceGroupHandleV1,
_data: &WorkspaceGroupData,
) {
for group in &mut state.workspace_state_mut().groups { for group in &mut state.workspace_state_mut().groups {
group.instances.retain(|i| i.id() != resource) group.instances.retain(|i| i != resource)
} }
} }
} }
@ -361,10 +371,15 @@ where
} }
} }
fn destroyed(state: &mut D, _client: ClientId, resource: ObjectId, _data: &WorkspaceData) { fn destroyed(
state: &mut D,
_client: ClientId,
resource: &ZcosmicWorkspaceHandleV1,
_data: &WorkspaceData,
) {
for group in &mut state.workspace_state_mut().groups { for group in &mut state.workspace_state_mut().groups {
for workspace in &mut group.workspaces { for workspace in &mut group.workspaces {
workspace.instances.retain(|i| i.id() != resource) workspace.instances.retain(|i| i != resource)
} }
} }
} }

View file

@ -3,7 +3,7 @@ use std::{ffi::OsString, os::unix::io::OwnedFd};
use crate::{ use crate::{
backend::render::cursor::{load_cursor_theme, Cursor, CursorShape}, backend::render::cursor::{load_cursor_theme, Cursor, CursorShape},
shell::{focus::target::KeyboardFocusTarget, CosmicSurface, Shell}, shell::{focus::target::KeyboardFocusTarget, CosmicSurface, Shell},
state::{Data, State}, state::State,
utils::prelude::*, utils::prelude::*,
wayland::{handlers::screencopy::PendingScreencopyBuffers, protocols::screencopy::SessionType}, wayland::{handlers::screencopy::PendingScreencopyBuffers, protocols::screencopy::SessionType},
}; };
@ -56,8 +56,8 @@ impl State {
display: _, display: _,
} => { } => {
let mut wm = match X11Wm::start_wm( let mut wm = match X11Wm::start_wm(
data.state.common.event_loop_handle.clone(), data.common.event_loop_handle.clone(),
data.state.common.display_handle.clone(), data.common.display_handle.clone(),
connection, connection,
client, client,
) { ) {
@ -83,11 +83,11 @@ impl State {
); );
} }
let xwayland_state = data.state.common.xwayland_state.as_mut().unwrap(); let xwayland_state = data.common.xwayland_state.as_mut().unwrap();
xwayland_state.xwm = Some(wm); xwayland_state.xwm = Some(wm);
} }
XWaylandEvent::Exited => { XWaylandEvent::Exited => {
if let Some(mut xwayland_state) = data.state.common.xwayland_state.take() { if let Some(mut xwayland_state) = data.common.xwayland_state.take() {
xwayland_state.xwm = None; xwayland_state.xwm = None;
} }
} }
@ -126,10 +126,9 @@ impl State {
} }
} }
impl XwmHandler for Data { impl XwmHandler for State {
fn xwm_state(&mut self, _xwm: XwmId) -> &mut X11Wm { fn xwm_state(&mut self, _xwm: XwmId) -> &mut X11Wm {
self.state self.common
.common
.xwayland_state .xwayland_state
.as_mut() .as_mut()
.and_then(|state| state.xwm.as_mut()) .and_then(|state| state.xwm.as_mut())
@ -146,27 +145,16 @@ impl XwmHandler for Data {
} }
let surface = CosmicSurface::X11(window.clone()); let surface = CosmicSurface::X11(window.clone());
if self if self.common.shell.element_for_surface(&surface).is_some() {
.state
.common
.shell
.element_for_surface(&surface)
.is_some()
{
return; return;
} }
let seat = self.state.common.last_active_seat().clone(); let seat = self.common.last_active_seat().clone();
self.state self.common.shell.pending_windows.push((surface, seat));
.common
.shell
.pending_windows
.push((surface, seat));
} }
fn map_window_notify(&mut self, _xwm: XwmId, surface: X11Surface) { fn map_window_notify(&mut self, _xwm: XwmId, surface: X11Surface) {
if let Some((window, seat)) = self if let Some((window, seat)) = self
.state
.common .common
.shell .shell
.pending_windows .pending_windows
@ -181,13 +169,12 @@ impl XwmHandler for Data {
.cloned() .cloned()
{ {
let output = seat.active_output(); let output = seat.active_output();
Shell::map_window(&mut self.state, &window, &output); Shell::map_window(self, &window, &output);
} }
} }
fn mapped_override_redirect_window(&mut self, _xwm: XwmId, window: X11Surface) { fn mapped_override_redirect_window(&mut self, _xwm: XwmId, window: X11Surface) {
if self if self
.state
.common .common
.shell .shell
.override_redirect_windows .override_redirect_windows
@ -196,26 +183,23 @@ impl XwmHandler for Data {
{ {
return; return;
} }
Shell::map_override_redirect(&mut self.state, window) Shell::map_override_redirect(self, window)
} }
fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) { fn unmapped_window(&mut self, _xwm: XwmId, window: X11Surface) {
let surface = CosmicSurface::X11(window.clone()); let surface = CosmicSurface::X11(window.clone());
if window.is_override_redirect() { if window.is_override_redirect() {
self.state self.common
.common
.shell .shell
.override_redirect_windows .override_redirect_windows
.retain(|or| or != &window); .retain(|or| or != &window);
} else if let Some((element, space)) = self } else if let Some((element, space)) = self
.state
.common .common
.shell .shell
.element_for_surface(&surface) .element_for_surface(&surface)
.cloned() .cloned()
.and_then(|element| { .and_then(|element| {
self.state self.common
.common
.shell .shell
.space_for_mut(&element) .space_for_mut(&element)
.map(|space| (element, space)) .map(|space| (element, space))
@ -229,27 +213,21 @@ impl XwmHandler for Data {
} }
let outputs = if let Some(wl_surface) = window.wl_surface() { let outputs = if let Some(wl_surface) = window.wl_surface() {
self.state self.common
.common
.shell .shell
.visible_outputs_for_surface(&wl_surface) .visible_outputs_for_surface(&wl_surface)
.collect::<Vec<_>>() .collect::<Vec<_>>()
} else { } else {
self.state self.common.shell.outputs().cloned().collect::<Vec<_>>()
.common
.shell
.outputs()
.cloned()
.collect::<Vec<_>>()
}; };
for output in outputs.iter() { for output in outputs.iter() {
self.state.common.shell.active_space_mut(output).refresh(); self.common.shell.active_space_mut(output).refresh();
} }
// screencopy // screencopy
let mut scheduled_sessions = window let mut scheduled_sessions = window
.wl_surface() .wl_surface()
.map(|wl_surface| self.state.schedule_workspace_sessions(&wl_surface)) .map(|wl_surface| self.schedule_workspace_sessions(&wl_surface))
.unwrap_or_default(); .unwrap_or_default();
for output in outputs.into_iter() { for output in outputs.into_iter() {
@ -258,8 +236,8 @@ impl XwmHandler for Data {
.get_or_insert_with(Vec::new) .get_or_insert_with(Vec::new)
.extend(sessions.borrow_mut().drain(..)); .extend(sessions.borrow_mut().drain(..));
} }
self.state.backend.schedule_render( self.backend.schedule_render(
&self.state.common.event_loop_handle, &self.common.event_loop_handle,
&output, &output,
scheduled_sessions.as_ref().map(|sessions| { scheduled_sessions.as_ref().map(|sessions| {
sessions sessions
@ -292,12 +270,11 @@ impl XwmHandler for Data {
// We only allow floating X11 windows to resize themselves. Nothing else // We only allow floating X11 windows to resize themselves. Nothing else
let mut current_geo = window.geometry(); let mut current_geo = window.geometry();
if let Some(mapped) = self if let Some(mapped) = self
.state
.common .common
.shell .shell
.element_for_surface(&CosmicSurface::X11(window.clone())) .element_for_surface(&CosmicSurface::X11(window.clone()))
{ {
let space = self.state.common.shell.space_for(mapped).unwrap(); let space = self.common.shell.space_for(mapped).unwrap();
if space.is_floating(mapped) { if space.is_floating(mapped) {
mapped.set_geometry(Rectangle::from_loc_and_size( mapped.set_geometry(Rectangle::from_loc_and_size(
current_geo.loc, current_geo.loc,
@ -334,7 +311,7 @@ impl XwmHandler for Data {
) { ) {
if window.is_override_redirect() { if window.is_override_redirect() {
if let Some(id) = above { if let Some(id) = above {
let or_windows = &mut self.state.common.shell.override_redirect_windows; let or_windows = &mut self.common.shell.override_redirect_windows;
if let Some(own_pos) = or_windows.iter().position(|or| or == &window) { if let Some(own_pos) = or_windows.iter().position(|or| or == &window) {
let compare_pos = or_windows let compare_pos = or_windows
.iter() .iter()
@ -348,7 +325,7 @@ impl XwmHandler for Data {
} }
let geo = window.geometry(); let geo = window.geometry();
for (output, overlap) in self.state.common.shell.outputs().cloned().map(|o| { for (output, overlap) in self.common.shell.outputs().cloned().map(|o| {
let intersection = o.geometry().intersection(geo); let intersection = o.geometry().intersection(geo);
(o, intersection) (o, intersection)
}) { }) {
@ -369,57 +346,35 @@ impl XwmHandler for Data {
resize_edge: smithay::xwayland::xwm::ResizeEdge, resize_edge: smithay::xwayland::xwm::ResizeEdge,
) { ) {
if let Some(wl_surface) = window.wl_surface() { if let Some(wl_surface) = window.wl_surface() {
let seat = self.state.common.last_active_seat().clone(); let seat = self.common.last_active_seat().clone();
Shell::resize_request( Shell::resize_request(self, &wl_surface, &seat, None, resize_edge.into())
&mut self.state,
&wl_surface,
&seat,
None,
resize_edge.into(),
)
} }
} }
fn move_request(&mut self, _xwm: XwmId, window: X11Surface, _button: u32) { fn move_request(&mut self, _xwm: XwmId, window: X11Surface, _button: u32) {
if let Some(wl_surface) = window.wl_surface() { if let Some(wl_surface) = window.wl_surface() {
let seat = self.state.common.last_active_seat().clone(); let seat = self.common.last_active_seat().clone();
Shell::move_request(&mut self.state, &wl_surface, &seat, None) Shell::move_request(self, &wl_surface, &seat, None)
} }
} }
fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) { fn maximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
let seat = self.state.common.last_active_seat(); let seat = self.common.last_active_seat();
let output = seat.active_output(); let output = seat.active_output();
let surface = CosmicSurface::X11(window); let surface = CosmicSurface::X11(window);
if let Some(mapped) = self if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
.state if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
.common
.shell
.element_for_surface(&surface)
.cloned()
{
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.maximize_request( workspace.maximize_request(&window, &output, self.common.event_loop_handle.clone())
&window,
&output,
self.state.common.event_loop_handle.clone(),
)
} }
} }
} }
fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) { fn unmaximize_request(&mut self, _xwm: XwmId, window: X11Surface) {
let surface = CosmicSurface::X11(window); let surface = CosmicSurface::X11(window);
if let Some(mapped) = self if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
.state if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
.common
.shell
.element_for_surface(&surface)
.cloned()
{
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.unmaximize_request(&window); workspace.unmaximize_request(&window);
} }
@ -427,23 +382,17 @@ impl XwmHandler for Data {
} }
fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { fn fullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
let seat = self.state.common.last_active_seat(); let seat = self.common.last_active_seat();
let output = seat.active_output(); let output = seat.active_output();
let surface = CosmicSurface::X11(window); let surface = CosmicSurface::X11(window);
if let Some(mapped) = self if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
.state if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
.common
.shell
.element_for_surface(&surface)
.cloned()
{
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.fullscreen_request( workspace.fullscreen_request(
&window, &window,
&output, &output,
self.state.common.event_loop_handle.clone(), self.common.event_loop_handle.clone(),
) )
} }
} }
@ -451,14 +400,8 @@ impl XwmHandler for Data {
fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) { fn unfullscreen_request(&mut self, _xwm: XwmId, window: X11Surface) {
let surface = CosmicSurface::X11(window); let surface = CosmicSurface::X11(window);
if let Some(mapped) = self if let Some(mapped) = self.common.shell.element_for_surface(&surface).cloned() {
.state if let Some(workspace) = self.common.shell.space_for_mut(&mapped) {
.common
.shell
.element_for_surface(&surface)
.cloned()
{
if let Some(workspace) = self.state.common.shell.space_for_mut(&mapped) {
let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap(); let (window, _) = mapped.windows().find(|(w, _)| w == &surface).unwrap();
workspace.unfullscreen_request(&window); workspace.unfullscreen_request(&window);
} }
@ -472,7 +415,7 @@ impl XwmHandler for Data {
mime_type: String, mime_type: String,
fd: OwnedFd, fd: OwnedFd,
) { ) {
let seat = self.state.common.last_active_seat(); let seat = self.common.last_active_seat();
match selection { match selection {
SelectionType::Clipboard => { SelectionType::Clipboard => {
if let Err(err) = request_data_device_client_selection(seat, mime_type, fd) { if let Err(err) = request_data_device_client_selection(seat, mime_type, fd) {
@ -494,39 +437,36 @@ impl XwmHandler for Data {
} }
fn allow_selection_access(&mut self, xwm: XwmId, _selection: SelectionType) -> bool { fn allow_selection_access(&mut self, xwm: XwmId, _selection: SelectionType) -> bool {
self.state.common.is_x_focused(xwm) self.common.is_x_focused(xwm)
} }
fn new_selection(&mut self, xwm: XwmId, selection: SelectionType, mime_types: Vec<String>) { fn new_selection(&mut self, xwm: XwmId, selection: SelectionType, mime_types: Vec<String>) {
trace!(?selection, ?mime_types, "Got Selection from Xwayland",); trace!(?selection, ?mime_types, "Got Selection from Xwayland",);
if self.state.common.is_x_focused(xwm) { if self.common.is_x_focused(xwm) {
let seat = self.state.common.last_active_seat(); let seat = self.common.last_active_seat();
match selection { match selection {
SelectionType::Clipboard => set_data_device_selection( SelectionType::Clipboard => {
&self.state.common.display_handle, set_data_device_selection(&self.common.display_handle, &seat, mime_types, xwm)
&seat, }
mime_types,
xwm,
),
SelectionType::Primary => { SelectionType::Primary => {
set_primary_selection(&self.state.common.display_handle, &seat, mime_types, xwm) set_primary_selection(&self.common.display_handle, &seat, mime_types, xwm)
} }
} }
} }
} }
fn cleared_selection(&mut self, xwm: XwmId, selection: SelectionType) { fn cleared_selection(&mut self, xwm: XwmId, selection: SelectionType) {
for seat in self.state.common.seats() { for seat in self.common.seats() {
match selection { match selection {
SelectionType::Clipboard => { SelectionType::Clipboard => {
if current_data_device_selection_userdata(seat).as_deref() == Some(&xwm) { if current_data_device_selection_userdata(seat).as_deref() == Some(&xwm) {
clear_data_device_selection(&self.state.common.display_handle, seat) clear_data_device_selection(&self.common.display_handle, seat)
} }
} }
SelectionType::Primary => { SelectionType::Primary => {
if current_primary_selection_userdata(seat).as_deref() == Some(&xwm) { if current_primary_selection_userdata(seat).as_deref() == Some(&xwm) {
clear_primary_selection(&self.state.common.display_handle, seat) clear_primary_selection(&self.common.display_handle, seat)
} }
} }
} }