Reduce idle CPU use and prioritize compositor rendering (#62)
Avoid background title updates when no shell window list is visible, and skip output and capture invalidation for titles outside compositor decorations. Preserve focused titles, fresh window lists and capture privacy. Request high EGL context priority with fallback, cover rendering and native title behavior in CI, and keep audio recording flowing while video capture is idle.
This commit is contained in:
1 parent
b66b19e4d9
commit
979afbd213
21 files changed
+876
-312
No files matched your search
@@ -1,3 +1,4 @@
|
||||
use std::cell::Cell;
|
||||
use std::error::Error;
|
||||
use std::os::fd::{FromRawFd, RawFd};
|
||||
use std::os::unix::net::UnixStream;
|
||||
@@ -77,6 +78,7 @@ pub(crate) struct ShellControl {
|
||||
shell: FereseShellV1,
|
||||
updates: Receiver<ControlUpdate>,
|
||||
wake: Wake,
|
||||
background_title_updates: Cell<bool>,
|
||||
}
|
||||
|
||||
pub(crate) struct ControlPoll {
|
||||
@@ -149,8 +151,9 @@ impl ShellControl {
|
||||
let connection = control_connection()?;
|
||||
let (globals, mut queue) = registry_queue_init::<ControlState>(&connection)?;
|
||||
let qh = queue.handle();
|
||||
let manager = globals.bind::<FereseShellManagerV1, _, _>(&qh, 7..=10, ())?;
|
||||
let manager = globals.bind::<FereseShellManagerV1, _, _>(&qh, 11..=11, ())?;
|
||||
let shell = manager.get_shell(&qh, ());
|
||||
shell.set_background_title_updates(0);
|
||||
let (sender, updates) = mpsc::channel();
|
||||
let wake = Wake(Arc::new(tokio::sync::Notify::new()));
|
||||
let mut state = ControlState::new(UpdateSender {
|
||||
@@ -172,9 +175,17 @@ impl ShellControl {
|
||||
shell,
|
||||
updates,
|
||||
wake,
|
||||
background_title_updates: Cell::new(false),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn set_background_title_updates(&self, enabled: bool) {
|
||||
if self.background_title_updates.replace(enabled) != enabled {
|
||||
self.shell.set_background_title_updates(u32::from(enabled));
|
||||
let _ = self.connection.flush();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn subscription(&self) -> cosmic::iced::Subscription<()> {
|
||||
cosmic::iced::Subscription::run_with(self.wake.clone(), Wake::stream)
|
||||
}
|
||||
@@ -597,6 +608,17 @@ mod tests {
|
||||
ControlState,
|
||||
wayland_client::EventQueue<ControlState>,
|
||||
UnixStream,
|
||||
) {
|
||||
control_fixture_version(6)
|
||||
}
|
||||
|
||||
fn control_fixture_version(
|
||||
version: u32,
|
||||
) -> (
|
||||
ShellControl,
|
||||
ControlState,
|
||||
wayland_client::EventQueue<ControlState>,
|
||||
UnixStream,
|
||||
) {
|
||||
let (socket, mut peer) = UnixStream::pair().unwrap();
|
||||
peer.set_read_timeout(Some(Duration::from_secs(1))).unwrap();
|
||||
@@ -604,7 +626,7 @@ mod tests {
|
||||
let queue = connection.new_event_queue::<ControlState>();
|
||||
let qh = queue.handle();
|
||||
let registry = connection.display().get_registry(&qh, ());
|
||||
let manager = registry.bind::<FereseShellManagerV1, _, _>(1, 6, &qh, ());
|
||||
let manager = registry.bind::<FereseShellManagerV1, _, _>(1, version, &qh, ());
|
||||
let shell = manager.get_shell(&qh, ());
|
||||
let (sender, updates) = mpsc::channel();
|
||||
let wake = Wake(Arc::new(tokio::sync::Notify::new()));
|
||||
@@ -623,10 +645,33 @@ mod tests {
|
||||
shell,
|
||||
updates,
|
||||
wake,
|
||||
background_title_updates: Cell::new(true),
|
||||
};
|
||||
(control, state, queue, peer)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn background_title_subscription_sends_only_changed_preferences() {
|
||||
let (control, _state, _queue, mut peer) = control_fixture_version(11);
|
||||
for enabled in [true, false, false, true, true] {
|
||||
control.set_background_title_updates(enabled);
|
||||
}
|
||||
for enabled in [0_u32, 1] {
|
||||
let (object, opcode, args) = read_request(&mut peer);
|
||||
let request = &FereseShellV1::interface().requests[usize::from(opcode)];
|
||||
assert_eq!(object, control.shell.id().protocol_id());
|
||||
assert_eq!(request.name, "set_background_title_updates");
|
||||
assert_eq!(args, enabled.to_ne_bytes());
|
||||
}
|
||||
peer.set_read_timeout(Some(Duration::from_millis(20)))
|
||||
.unwrap();
|
||||
let error = peer.read(&mut [0; 8]).unwrap_err();
|
||||
assert!(matches!(
|
||||
error.kind(),
|
||||
std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut
|
||||
));
|
||||
}
|
||||
|
||||
fn dispatch_event(
|
||||
control: &ShellControl,
|
||||
state: &mut ControlState,
|
||||
|
||||
@@ -1109,6 +1109,19 @@ impl cosmic::Application for FereseShell {
|
||||
}
|
||||
};
|
||||
self.flush_config_error();
|
||||
if let Some(control) = &self.control {
|
||||
control.set_background_title_updates(
|
||||
self.launcher.is_some()
|
||||
|| self.outputs.iter().any(|output| {
|
||||
output.runtime.hub.as_ref().is_some_and(|hub| {
|
||||
hub.borrow().hub.mode()
|
||||
== ferese_panel::morph::Mode::Expanded(
|
||||
ferese_panel::morph::Content::Workspaces,
|
||||
)
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
task
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user