From 5af3abeb93e187f7f9da03f670ccd18d979f63a7 Mon Sep 17 00:00:00 2001 From: Lucy Date: Tue, 15 Feb 2022 17:41:01 -0500 Subject: [PATCH] Well it uh, mostly works. --- applets/cosmic-applet-graphics/Cargo.toml | 2 +- applets/cosmic-applet-graphics/src/dbus.rs | 6 +- .../cosmic-applet-graphics/src/graphics.rs | 9 +-- applets/cosmic-applet-graphics/src/main.rs | 63 ++++++++++++++++--- .../cosmic-applet-graphics/src/mode_box.rs | 12 +++- 5 files changed, 77 insertions(+), 15 deletions(-) diff --git a/applets/cosmic-applet-graphics/Cargo.toml b/applets/cosmic-applet-graphics/Cargo.toml index 472298aa..6b9a477a 100644 --- a/applets/cosmic-applet-graphics/Cargo.toml +++ b/applets/cosmic-applet-graphics/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -gtk4 = "0.4.6" +gtk4 = { version = "0.4.6", features = ["v4_2"] } once_cell = "1.9.0" relm4-macros = "0.4.2" tokio = { version = "1.16.1", features = ["full"] } diff --git a/applets/cosmic-applet-graphics/src/dbus.rs b/applets/cosmic-applet-graphics/src/dbus.rs index f6c4b853..177b015c 100644 --- a/applets/cosmic-applet-graphics/src/dbus.rs +++ b/applets/cosmic-applet-graphics/src/dbus.rs @@ -20,7 +20,11 @@ use zbus::dbus_proxy; -#[dbus_proxy(interface = "com.system76.PowerDaemon")] +#[dbus_proxy( + interface = "com.system76.PowerDaemon", + default_service = "com.system76.PowerDaemon", + default_path = "/com/system76/PowerDaemon" +)] trait PowerDaemon { /// Balanced method fn balanced(&self) -> zbus::Result<()>; diff --git a/applets/cosmic-applet-graphics/src/graphics.rs b/applets/cosmic-applet-graphics/src/graphics.rs index 762642fd..339c3153 100644 --- a/applets/cosmic-applet-graphics/src/graphics.rs +++ b/applets/cosmic-applet-graphics/src/graphics.rs @@ -2,10 +2,11 @@ use crate::dbus::PowerDaemonProxy; use zbus::Result; +#[derive(PartialEq, Eq)] pub enum Graphics { Integrated, Hybrid, - External, + Nvidia, Compute, } @@ -14,7 +15,7 @@ pub async fn get_current_graphics(daemon: &PowerDaemonProxy<'_>) -> Result Ok(Graphics::Integrated), "hybrid" => Ok(Graphics::Hybrid), - "external" => Ok(Graphics::External), + "nvidia" => Ok(Graphics::Nvidia), "compute" => Ok(Graphics::Compute), _ => panic!("Unknown graphics profile: {}", graphics), } @@ -25,7 +26,7 @@ pub async fn get_default_graphics(daemon: &PowerDaemonProxy<'_>) -> Result Ok(Graphics::Integrated), "hybrid" => Ok(Graphics::Hybrid), - "external" => Ok(Graphics::External), + "nvidia" => Ok(Graphics::Nvidia), "compute" => Ok(Graphics::Compute), _ => panic!("Unknown graphics profile: {}", graphics), } @@ -35,7 +36,7 @@ pub async fn set_graphics(daemon: &PowerDaemonProxy<'_>, graphics: Graphics) -> let graphics_str = match graphics { Graphics::Integrated => "integrated", Graphics::Hybrid => "hybrid", - Graphics::External => "external", + Graphics::Nvidia => "nvidia", Graphics::Compute => "compute", }; daemon.set_graphics(graphics_str).await diff --git a/applets/cosmic-applet-graphics/src/main.rs b/applets/cosmic-applet-graphics/src/main.rs index e39ea6ab..97deb0ab 100644 --- a/applets/cosmic-applet-graphics/src/main.rs +++ b/applets/cosmic-applet-graphics/src/main.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later +#![allow(unused_parens, clippy::double_parens)] // needed for a quirk in the view! macro + #[macro_use] extern crate relm4_macros; @@ -8,7 +10,8 @@ pub mod graphics; pub mod mode_box; pub mod profile; -use gtk4::{gio::ApplicationFlags, prelude::*, Orientation}; +use self::{dbus::PowerDaemonProxy, graphics::Graphics, mode_box::ModeSelection}; +use gtk4::{gio::ApplicationFlags, prelude::*, Label, ListBox, ListBoxRow, Orientation, Separator}; use once_cell::sync::Lazy; use tokio::runtime::Runtime; @@ -23,18 +26,26 @@ fn main() { application.run(); } -async fn get_current_graphics() -> zbus::Result { +async fn get_current_graphics() -> zbus::Result { let connection = zbus::Connection::system().await?; - let proxy = dbus::PowerDaemonProxy::new(&connection).await?; + let proxy = PowerDaemonProxy::new(&connection).await?; graphics::get_current_graphics(&proxy).await } -async fn set_graphics(graphics_mode: graphics::Graphics) -> zbus::Result<()> { +async fn set_graphics(graphics_mode: Graphics) -> zbus::Result<()> { let connection = zbus::Connection::system().await?; - let proxy = dbus::PowerDaemonProxy::new(&connection).await?; + let proxy = PowerDaemonProxy::new(&connection).await?; graphics::set_graphics(&proxy, graphics_mode).await } +fn row_clicked(_: &ListBox, row: &ListBoxRow) { + let child = row.child().expect("UNEXPECTED: row has no child"); + let selector = child + .downcast::() + .expect("UNEXPECTED: child is not a mode selector"); + selector.emit_activate(); +} + fn build_ui(application: >k4::Application) { let window = gtk4::ApplicationWindow::builder() .application(application) @@ -53,14 +64,52 @@ fn build_ui(application: >k4::Application) { set_margin_bottom: 20, set_margin_start: 24, set_margin_end: 24, - append: mode_label = >k4::Label { + append: mode_label = &Label { set_text: "Graphics Mode" }, - append: separator = >k4::Separator { + append: separator = &Separator { set_orientation: Orientation::Horizontal + }, + append: graphics_modes_list = &ListBox { + connect_row_activated: row_clicked, + append: integrated_selector = &ModeSelection { + set_title: "Integrated Graphics", + set_description: "Disables external displays. Requires Restart.", + set_active: (current_graphics == Graphics::Integrated), + connect_toggled: |_| { + RT.block_on(set_graphics(Graphics::Integrated)).expect("failed to set graphics"); + } + }, + append: nvidia_selector = &ModeSelection { + set_title: "NVIDIA Graphics", + set_group: Some(&integrated_selector), + set_active: (current_graphics == Graphics::Nvidia), + connect_toggled: |_| { + RT.block_on(set_graphics(Graphics::Nvidia)).expect("failed to set graphics"); + } + }, + append: hybrid_selector = &ModeSelection { + set_title: "Hybrid Graphics", + set_description: "Requires Restart.", + set_group: Some(&integrated_selector), + set_active: (current_graphics == Graphics::Hybrid), + connect_toggled: |_| { + RT.block_on(set_graphics(Graphics::Hybrid)).expect("failed to set graphics"); + } + }, + append: compute_selector = &ModeSelection { + set_title: "Compute Graphics", + set_description: "Disables external displays. Requires Restart.", + set_group: Some(&integrated_selector), + set_active: (current_graphics == Graphics::Compute), + connect_toggled: |_| { + RT.block_on(set_graphics(Graphics::Compute)).expect("failed to set graphics"); + } + }, } } } + window.set_child(Some(&main_box)); window.show(); } diff --git a/applets/cosmic-applet-graphics/src/mode_box.rs b/applets/cosmic-applet-graphics/src/mode_box.rs index a8258388..d3d9f070 100644 --- a/applets/cosmic-applet-graphics/src/mode_box.rs +++ b/applets/cosmic-applet-graphics/src/mode_box.rs @@ -36,14 +36,20 @@ impl ModeSelection { self.inner().check.set_active(setting) } - pub fn set_group(&self, group: Option<&impl IsA>) { - self.inner().check.set_group(group) + pub fn set_group(&self, group: Option<&ModeSelection>) { + self.inner() + .check + .set_group(group.map(|x| &x.inner().check)) } pub fn connect_toggled(&self, f: F) { self.inner().check.connect_toggled(f); } + pub fn emit_activate(&self) { + self.inner().check.emit_activate(); + } + fn inner(&self) -> &ModeSelectionImp { ModeSelectionImp::from_instance(self) } @@ -92,12 +98,14 @@ impl ObjectImpl for ModeSelectionImp { self.description.hide(); self.label_box.set_orientation(Orientation::Vertical); + self.label_box.set_hexpand(true); self.label_box.append(&self.label); self.label_box.append(&self.description); self.inner_box.set_orientation(Orientation::Horizontal); self.inner_box.append(&self.label_box); self.inner_box.append(&self.check); + self.inner_box.set_parent(obj); } fn dispose(&self, _obj: &Self::Type) {