From e2951041990983eb100dde664607de5330e50b13 Mon Sep 17 00:00:00 2001 From: Christian Duerr Date: Mon, 27 Jan 2020 03:56:54 +0100 Subject: [PATCH] Remove Wayland theme intermediates (#1209) * Remove Wayland theme intermediates This removes the intermediate struct for passing a Wayland theme to allow the user direct implementation of the trait. By passing the trait directly, it is possible for downstream users to have more freedom with customization without relying on winit to offer these options as fields. It should also make maintenance easier, since winit already doesn't implement all the functions which are offered by the smithay client toolkit. * Reimplement SCTK's Theme and ButtonState * Fix style issues * Remove public signature * Format code * Add change log entry Co-authored-by: Murarth --- CHANGELOG.md | 1 + src/platform/unix.rs | 169 +++++++++++++++++++++++++------------------ 2 files changed, 98 insertions(+), 72 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd299bdc..78cfc83e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - **Breaking:** `WindowEvent::CursorMoved` changed to `f64` units, preserving high-precision data supplied by most backends - On Wayland, fix coordinates in mouse events when scale factor isn't 1 - On Web, add the ability to provide a custom canvas +- **Breaking:** On Wayland, the `WaylandTheme` struct has been replaced with a `Theme` trait, allowing for extra configuration # 0.20.0 (2020-01-05) diff --git a/src/platform/unix.rs b/src/platform/unix.rs index 0484d71e..12711506 100644 --- a/src/platform/unix.rs +++ b/src/platform/unix.rs @@ -2,7 +2,7 @@ use std::{os::raw, ptr, sync::Arc}; -use smithay_client_toolkit::window::{ButtonState, Theme}; +use smithay_client_toolkit::window::{ButtonState as SCTKButtonState, Theme as SCTKTheme}; use crate::{ dpi::Size, @@ -23,74 +23,6 @@ pub use crate::platform_impl::x11; pub use crate::platform_impl::{x11::util::WindowType as XWindowType, XNotSupported}; -/// Theme for wayland client side decorations -/// -/// Colors must be in ARGB8888 format -pub struct WaylandTheme { - /// Primary color when the window is focused - pub primary_active: [u8; 4], - /// Primary color when the window is unfocused - pub primary_inactive: [u8; 4], - /// Secondary color when the window is focused - pub secondary_active: [u8; 4], - /// Secondary color when the window is unfocused - pub secondary_inactive: [u8; 4], - /// Close button color when hovered over - pub close_button_hovered: [u8; 4], - /// Close button color - pub close_button: [u8; 4], - /// Close button color when hovered over - pub maximize_button_hovered: [u8; 4], - /// Maximize button color - pub maximize_button: [u8; 4], - /// Minimize button color when hovered over - pub minimize_button_hovered: [u8; 4], - /// Minimize button color - pub minimize_button: [u8; 4], -} - -struct WaylandThemeObject(WaylandTheme); - -impl Theme for WaylandThemeObject { - fn get_primary_color(&self, active: bool) -> [u8; 4] { - if active { - self.0.primary_active - } else { - self.0.primary_inactive - } - } - - // Used for division line - fn get_secondary_color(&self, active: bool) -> [u8; 4] { - if active { - self.0.secondary_active - } else { - self.0.secondary_inactive - } - } - - fn get_close_button_color(&self, state: ButtonState) -> [u8; 4] { - match state { - ButtonState::Hovered => self.0.close_button_hovered, - _ => self.0.close_button, - } - } - - fn get_maximize_button_color(&self, state: ButtonState) -> [u8; 4] { - match state { - ButtonState::Hovered => self.0.maximize_button_hovered, - _ => self.0.maximize_button, - } - } - - fn get_minimize_button_color(&self, state: ButtonState) -> [u8; 4] { - match state { - ButtonState::Hovered => self.0.minimize_button_hovered, - _ => self.0.minimize_button, - } - } -} - /// Additional methods on `EventLoopWindowTarget` that are specific to Unix. pub trait EventLoopWindowTargetExtUnix { /// True if the `EventLoopWindowTarget` uses Wayland. @@ -275,7 +207,7 @@ pub trait WindowExtUnix { fn wayland_display(&self) -> Option<*mut raw::c_void>; /// Sets the color theme of the client side window decorations on wayland - fn set_wayland_theme(&self, theme: WaylandTheme); + fn set_wayland_theme(&self, theme: T); /// Check if the window is ready for drawing /// @@ -353,9 +285,9 @@ impl WindowExtUnix for Window { } #[inline] - fn set_wayland_theme(&self, theme: WaylandTheme) { + fn set_wayland_theme(&self, theme: T) { match self.window { - LinuxWindow::Wayland(ref w) => w.set_theme(WaylandThemeObject(theme)), + LinuxWindow::Wayland(ref w) => w.set_theme(WaylandTheme(theme)), _ => {} } } @@ -461,3 +393,96 @@ impl MonitorHandleExtUnix for MonitorHandle { self.inner.native_identifier() } } + +/// Wrapper for implementing SCTK's theme trait. +struct WaylandTheme(T); + +pub trait Theme: Send + 'static { + /// Primary color of the scheme. + fn primary_color(&self, window_active: bool) -> [u8; 4]; + + /// Secondary color of the scheme. + fn secondary_color(&self, window_active: bool) -> [u8; 4]; + + /// Color for the close button. + fn close_button_color(&self, status: ButtonState) -> [u8; 4]; + + /// Icon color for the close button, defaults to the secondary color. + #[allow(unused_variables)] + fn close_button_icon_color(&self, status: ButtonState) -> [u8; 4] { + self.secondary_color(true) + } + + /// Background color for the maximize button. + fn maximize_button_color(&self, status: ButtonState) -> [u8; 4]; + + /// Icon color for the maximize button, defaults to the secondary color. + #[allow(unused_variables)] + fn maximize_button_icon_color(&self, status: ButtonState) -> [u8; 4] { + self.secondary_color(true) + } + + /// Background color for the minimize button. + fn minimize_button_color(&self, status: ButtonState) -> [u8; 4]; + + /// Icon color for the minimize button, defaults to the secondary color. + #[allow(unused_variables)] + fn minimize_button_icon_color(&self, status: ButtonState) -> [u8; 4] { + self.secondary_color(true) + } +} + +impl SCTKTheme for WaylandTheme { + fn get_primary_color(&self, active: bool) -> [u8; 4] { + self.0.primary_color(active) + } + + fn get_secondary_color(&self, active: bool) -> [u8; 4] { + self.0.secondary_color(active) + } + + fn get_close_button_color(&self, status: SCTKButtonState) -> [u8; 4] { + self.0.close_button_color(ButtonState::from_sctk(status)) + } + + fn get_close_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4] { + self.0.close_button_color(ButtonState::from_sctk(status)) + } + + fn get_maximize_button_color(&self, status: SCTKButtonState) -> [u8; 4] { + self.0.maximize_button_color(ButtonState::from_sctk(status)) + } + + fn get_maximize_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4] { + self.0 + .maximize_button_icon_color(ButtonState::from_sctk(status)) + } + + fn get_minimize_button_color(&self, status: SCTKButtonState) -> [u8; 4] { + self.0.minimize_button_color(ButtonState::from_sctk(status)) + } + + fn get_minimize_button_icon_color(&self, status: SCTKButtonState) -> [u8; 4] { + self.0 + .minimize_button_icon_color(ButtonState::from_sctk(status)) + } +} + +pub enum ButtonState { + /// Button is being hovered over by pointer. + Hovered, + /// Button is not being hovered over by pointer. + Idle, + /// Button is disabled. + Disabled, +} + +impl ButtonState { + fn from_sctk(button_state: SCTKButtonState) -> Self { + match button_state { + SCTKButtonState::Hovered => Self::Hovered, + SCTKButtonState::Idle => Self::Idle, + SCTKButtonState::Disabled => Self::Disabled, + } + } +}