Merge pull request #186 from pop-os/update-smithay_jammy
chore: Update deps
This commit is contained in:
commit
a149b4262f
42 changed files with 1332 additions and 1126 deletions
1343
Cargo.lock
generated
1343
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
27
Cargo.toml
27
Cargo.toml
|
|
@ -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" }
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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") {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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"))?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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],
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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<_>>();
|
||||||
|
|
|
||||||
|
|
@ -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)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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, ¤t_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, ¤t_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,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
73
src/main.rs
73
src/main.rs
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
15
src/state.rs
15
src/state.rs
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)) => {
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ pub fn update_reactive_popups<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PopupKind::InputMethod(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
160
src/xwayland.rs
160
src/xwayland.rs
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue