feat: Add support for on-demand window focus on wayland (#1215)
* feat: Add support for on-demand window focus on wayland * fix: cargo fmt * Update CHANGELOG.md with OnDemand focusable * fix: add v0_6 feature to gtk-layer-shell in eww/cargo.toml
This commit is contained in:
parent
95124ad274
commit
2c81b3fbc7
6 changed files with 52 additions and 19 deletions
|
@ -18,6 +18,7 @@ All notable changes to eww will be listed here, starting at changes since versio
|
|||
- Fix wayland monitor names support (By: dragonnn)
|
||||
|
||||
### Features
|
||||
- Add OnDemand support for focusable on wayland (By: GallowsDove)
|
||||
- Update rust toolchain to 1.81.0 (By: w-lfchen)
|
||||
- Add `:fill-svg` and `:preserve-aspect-ratio` properties to images (By: hypernova7, w-lfchen)
|
||||
- Add `:truncate` property to labels, disabled by default (except in cases where truncation would be enabled in version `0.5.0` and before) (By: Rayzeq).
|
||||
|
|
|
@ -20,7 +20,7 @@ eww_shared_util.workspace = true
|
|||
yuck.workspace = true
|
||||
notifier_host.workspace = true
|
||||
|
||||
gtk-layer-shell = { version = "0.8.1", optional = true }
|
||||
gtk-layer-shell = { version = "0.8.1", optional = true, features=["v0_6"] }
|
||||
gdkx11 = { version = "0.18", optional = true }
|
||||
x11rb = { version = "0.13.1", features = ["randr"], optional = true }
|
||||
gdk-sys = "0.18.0"
|
||||
|
|
|
@ -28,14 +28,14 @@ impl DisplayBackend for NoBackend {
|
|||
|
||||
#[cfg(feature = "wayland")]
|
||||
mod platform_wayland {
|
||||
use super::DisplayBackend;
|
||||
use crate::{widgets::window::Window, window_initiator::WindowInitiator};
|
||||
use gtk::gdk;
|
||||
use gtk::prelude::*;
|
||||
use gtk_layer_shell::LayerShell;
|
||||
use gtk_layer_shell::{KeyboardMode, LayerShell};
|
||||
use yuck::config::backend_window_options::WlWindowFocusable;
|
||||
use yuck::config::{window_definition::WindowStacking, window_geometry::AnchorAlignment};
|
||||
|
||||
use super::DisplayBackend;
|
||||
|
||||
pub struct WaylandBackend;
|
||||
|
||||
impl DisplayBackend for WaylandBackend {
|
||||
|
@ -70,7 +70,11 @@ mod platform_wayland {
|
|||
}
|
||||
|
||||
// Sets the keyboard interactivity
|
||||
window.set_keyboard_interactivity(window_init.backend_options.wayland.focusable);
|
||||
match window_init.backend_options.wayland.focusable {
|
||||
WlWindowFocusable::None => window.set_keyboard_mode(KeyboardMode::None),
|
||||
WlWindowFocusable::Exclusive => window.set_keyboard_mode(KeyboardMode::Exclusive),
|
||||
WlWindowFocusable::OnDemand => window.set_keyboard_mode(KeyboardMode::OnDemand),
|
||||
}
|
||||
|
||||
if let Some(geometry) = window_init.geometry {
|
||||
// Positioning surface
|
||||
|
|
|
@ -7,6 +7,7 @@ use simplexpr::{
|
|||
SimplExpr,
|
||||
};
|
||||
|
||||
use super::{attributes::Attributes, window_definition::EnumParseError};
|
||||
use crate::{
|
||||
enum_parse,
|
||||
error::DiagResult,
|
||||
|
@ -14,8 +15,7 @@ use crate::{
|
|||
value::{coords, NumWithUnit},
|
||||
};
|
||||
use eww_shared_util::{Span, VarName};
|
||||
|
||||
use super::{attributes::Attributes, window_definition::EnumParseError};
|
||||
use simplexpr::dynval::ConversionError;
|
||||
|
||||
use crate::error::{DiagError, DiagResultExt};
|
||||
|
||||
|
@ -27,6 +27,8 @@ pub enum Error {
|
|||
CoordsError(#[from] coords::Error),
|
||||
#[error(transparent)]
|
||||
EvalError(#[from] EvalError),
|
||||
#[error(transparent)]
|
||||
ConversionError(#[from] ConversionError),
|
||||
}
|
||||
|
||||
/// Backend-specific options of a window
|
||||
|
@ -45,6 +47,7 @@ impl BackendWindowOptionsDef {
|
|||
pub fn from_attrs(attrs: &mut Attributes) -> DiagResult<Self> {
|
||||
let struts = attrs.ast_optional("reserve")?;
|
||||
let window_type = attrs.ast_optional("windowtype")?;
|
||||
let focusable = attrs.ast_optional("focusable")?;
|
||||
let x11 = X11BackendWindowOptionsDef {
|
||||
sticky: attrs.ast_optional("sticky")?,
|
||||
struts,
|
||||
|
@ -53,7 +56,7 @@ impl BackendWindowOptionsDef {
|
|||
};
|
||||
let wayland = WlBackendWindowOptionsDef {
|
||||
exclusive: attrs.ast_optional("exclusive")?,
|
||||
focusable: attrs.ast_optional("focusable")?,
|
||||
focusable,
|
||||
namespace: attrs.ast_optional("namespace")?,
|
||||
};
|
||||
|
||||
|
@ -109,7 +112,7 @@ impl X11BackendWindowOptionsDef {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
|
||||
pub struct WlBackendWindowOptions {
|
||||
pub exclusive: bool,
|
||||
pub focusable: bool,
|
||||
pub focusable: WlWindowFocusable,
|
||||
pub namespace: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -122,10 +125,13 @@ pub struct WlBackendWindowOptionsDef {
|
|||
}
|
||||
|
||||
impl WlBackendWindowOptionsDef {
|
||||
fn eval(&self, local_variables: &HashMap<VarName, DynVal>) -> Result<WlBackendWindowOptions, EvalError> {
|
||||
fn eval(&self, local_variables: &HashMap<VarName, DynVal>) -> Result<WlBackendWindowOptions, Error> {
|
||||
Ok(WlBackendWindowOptions {
|
||||
exclusive: eval_opt_expr_as_bool(&self.exclusive, false, local_variables)?,
|
||||
focusable: eval_opt_expr_as_bool(&self.focusable, false, local_variables)?,
|
||||
focusable: match &self.focusable {
|
||||
Some(expr) => WlWindowFocusable::from_dynval(&expr.eval(local_variables)?)?,
|
||||
None => WlWindowFocusable::default(),
|
||||
},
|
||||
namespace: match &self.namespace {
|
||||
Some(expr) => Some(expr.eval(local_variables)?.as_string()?),
|
||||
None => None,
|
||||
|
@ -145,6 +151,28 @@ fn eval_opt_expr_as_bool(
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, smart_default::SmartDefault, serde::Serialize)]
|
||||
pub enum WlWindowFocusable {
|
||||
#[default]
|
||||
None,
|
||||
Exclusive,
|
||||
OnDemand,
|
||||
}
|
||||
impl FromStr for WlWindowFocusable {
|
||||
type Err = EnumParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
enum_parse! { "focusable", s,
|
||||
"none" => Self::None,
|
||||
"exclusive" => Self::Exclusive,
|
||||
"ondemand" => Self::OnDemand,
|
||||
// legacy support
|
||||
"true" => Self::Exclusive,
|
||||
"false" => Self::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Window type of an x11 window
|
||||
#[derive(Debug, Clone, PartialEq, Eq, smart_default::SmartDefault, serde::Serialize)]
|
||||
pub enum X11WindowType {
|
||||
|
@ -182,7 +210,7 @@ pub enum Side {
|
|||
Bottom,
|
||||
}
|
||||
|
||||
impl std::str::FromStr for Side {
|
||||
impl FromStr for Side {
|
||||
type Err = EnumParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Side, Self::Err> {
|
||||
|
|
|
@ -87,10 +87,10 @@ Depending on if you are using X11 or Wayland, some additional properties exist:
|
|||
#### Wayland
|
||||
|
||||
| Property | Description |
|
||||
| ----------: | ------------------------------------------------------------ |
|
||||
| ----------: |------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `stacking` | Where the window should appear in the stack. Possible values: `fg`, `bg`, `overlay`, `bottom`. |
|
||||
| `exclusive` | Whether the compositor should reserve space for the window automatically. Either `true` or `false`. |
|
||||
| `focusable` | Whether the window should be able to be focused. This is necessary for any widgets that use the keyboard to work. Either `true` or `false`. |
|
||||
| `focusable` | Whether the window should be able to be focused. This is necessary for any widgets that use the keyboard to work. Possible values: `none`, `exclusive` and `ondemand`. |
|
||||
| `namespace` | Set the wayland layersurface namespace eww uses. Accepts a `string` value. |
|
||||
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
(defwindow data-structures
|
||||
:monitor 0
|
||||
:exclusive false
|
||||
:focusable false
|
||||
:focusable none
|
||||
:geometry (geometry
|
||||
:anchor "center"
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue