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)
|
- Fix wayland monitor names support (By: dragonnn)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
- Add OnDemand support for focusable on wayland (By: GallowsDove)
|
||||||
- Update rust toolchain to 1.81.0 (By: w-lfchen)
|
- 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 `: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).
|
- 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
|
yuck.workspace = true
|
||||||
notifier_host.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 }
|
gdkx11 = { version = "0.18", optional = true }
|
||||||
x11rb = { version = "0.13.1", features = ["randr"], optional = true }
|
x11rb = { version = "0.13.1", features = ["randr"], optional = true }
|
||||||
gdk-sys = "0.18.0"
|
gdk-sys = "0.18.0"
|
||||||
|
|
|
@ -28,14 +28,14 @@ impl DisplayBackend for NoBackend {
|
||||||
|
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
mod platform_wayland {
|
mod platform_wayland {
|
||||||
|
use super::DisplayBackend;
|
||||||
use crate::{widgets::window::Window, window_initiator::WindowInitiator};
|
use crate::{widgets::window::Window, window_initiator::WindowInitiator};
|
||||||
use gtk::gdk;
|
use gtk::gdk;
|
||||||
use gtk::prelude::*;
|
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 yuck::config::{window_definition::WindowStacking, window_geometry::AnchorAlignment};
|
||||||
|
|
||||||
use super::DisplayBackend;
|
|
||||||
|
|
||||||
pub struct WaylandBackend;
|
pub struct WaylandBackend;
|
||||||
|
|
||||||
impl DisplayBackend for WaylandBackend {
|
impl DisplayBackend for WaylandBackend {
|
||||||
|
@ -70,7 +70,11 @@ mod platform_wayland {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the keyboard interactivity
|
// 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 {
|
if let Some(geometry) = window_init.geometry {
|
||||||
// Positioning surface
|
// Positioning surface
|
||||||
|
|
|
@ -7,6 +7,7 @@ use simplexpr::{
|
||||||
SimplExpr,
|
SimplExpr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use super::{attributes::Attributes, window_definition::EnumParseError};
|
||||||
use crate::{
|
use crate::{
|
||||||
enum_parse,
|
enum_parse,
|
||||||
error::DiagResult,
|
error::DiagResult,
|
||||||
|
@ -14,8 +15,7 @@ use crate::{
|
||||||
value::{coords, NumWithUnit},
|
value::{coords, NumWithUnit},
|
||||||
};
|
};
|
||||||
use eww_shared_util::{Span, VarName};
|
use eww_shared_util::{Span, VarName};
|
||||||
|
use simplexpr::dynval::ConversionError;
|
||||||
use super::{attributes::Attributes, window_definition::EnumParseError};
|
|
||||||
|
|
||||||
use crate::error::{DiagError, DiagResultExt};
|
use crate::error::{DiagError, DiagResultExt};
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ pub enum Error {
|
||||||
CoordsError(#[from] coords::Error),
|
CoordsError(#[from] coords::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
EvalError(#[from] EvalError),
|
EvalError(#[from] EvalError),
|
||||||
|
#[error(transparent)]
|
||||||
|
ConversionError(#[from] ConversionError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Backend-specific options of a window
|
/// Backend-specific options of a window
|
||||||
|
@ -45,6 +47,7 @@ impl BackendWindowOptionsDef {
|
||||||
pub fn from_attrs(attrs: &mut Attributes) -> DiagResult<Self> {
|
pub fn from_attrs(attrs: &mut Attributes) -> DiagResult<Self> {
|
||||||
let struts = attrs.ast_optional("reserve")?;
|
let struts = attrs.ast_optional("reserve")?;
|
||||||
let window_type = attrs.ast_optional("windowtype")?;
|
let window_type = attrs.ast_optional("windowtype")?;
|
||||||
|
let focusable = attrs.ast_optional("focusable")?;
|
||||||
let x11 = X11BackendWindowOptionsDef {
|
let x11 = X11BackendWindowOptionsDef {
|
||||||
sticky: attrs.ast_optional("sticky")?,
|
sticky: attrs.ast_optional("sticky")?,
|
||||||
struts,
|
struts,
|
||||||
|
@ -53,7 +56,7 @@ impl BackendWindowOptionsDef {
|
||||||
};
|
};
|
||||||
let wayland = WlBackendWindowOptionsDef {
|
let wayland = WlBackendWindowOptionsDef {
|
||||||
exclusive: attrs.ast_optional("exclusive")?,
|
exclusive: attrs.ast_optional("exclusive")?,
|
||||||
focusable: attrs.ast_optional("focusable")?,
|
focusable,
|
||||||
namespace: attrs.ast_optional("namespace")?,
|
namespace: attrs.ast_optional("namespace")?,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,7 +112,7 @@ impl X11BackendWindowOptionsDef {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
|
||||||
pub struct WlBackendWindowOptions {
|
pub struct WlBackendWindowOptions {
|
||||||
pub exclusive: bool,
|
pub exclusive: bool,
|
||||||
pub focusable: bool,
|
pub focusable: WlWindowFocusable,
|
||||||
pub namespace: Option<String>,
|
pub namespace: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,10 +125,13 @@ pub struct WlBackendWindowOptionsDef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
Ok(WlBackendWindowOptions {
|
||||||
exclusive: eval_opt_expr_as_bool(&self.exclusive, false, local_variables)?,
|
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 {
|
namespace: match &self.namespace {
|
||||||
Some(expr) => Some(expr.eval(local_variables)?.as_string()?),
|
Some(expr) => Some(expr.eval(local_variables)?.as_string()?),
|
||||||
None => None,
|
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
|
/// Window type of an x11 window
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, smart_default::SmartDefault, serde::Serialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, smart_default::SmartDefault, serde::Serialize)]
|
||||||
pub enum X11WindowType {
|
pub enum X11WindowType {
|
||||||
|
@ -182,7 +210,7 @@ pub enum Side {
|
||||||
Bottom,
|
Bottom,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for Side {
|
impl FromStr for Side {
|
||||||
type Err = EnumParseError;
|
type Err = EnumParseError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Side, Self::Err> {
|
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
|
#### Wayland
|
||||||
|
|
||||||
| Property | Description |
|
| Property | Description |
|
||||||
| ----------: | ------------------------------------------------------------ |
|
| ----------: |------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `stacking` | Where the window should appear in the stack. Possible values: `fg`, `bg`, `overlay`, `bottom`. |
|
| `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`. |
|
| `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. |
|
| `namespace` | Set the wayland layersurface namespace eww uses. Accepts a `string` value. |
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
(defwindow data-structures
|
(defwindow data-structures
|
||||||
:monitor 0
|
:monitor 0
|
||||||
:exclusive false
|
:exclusive false
|
||||||
:focusable false
|
:focusable none
|
||||||
:geometry (geometry
|
:geometry (geometry
|
||||||
:anchor "center"
|
:anchor "center"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue