Set _NET_WM_WINDOW_TYPE and related fields properly (#176)
* add windowtype attribute to window tag. set _NET_WM_WINDOW_TYPE property for x11 * up * remove strum and strum_macros dependencies * Update configuration.md * Update window_definition.rs * Update window_definition.rs should work now Co-authored-by: Midnight Exigent <6959267-midnightexigent@users.noreply.gitlab.com>
This commit is contained in:
parent
1ed4925eb1
commit
31730bea32
6 changed files with 104 additions and 19 deletions
24
Cargo.lock
generated
24
Cargo.lock
generated
|
@ -389,6 +389,8 @@ dependencies = [
|
|||
"simple-signal",
|
||||
"smart-default",
|
||||
"structopt",
|
||||
"strum 0.20.0",
|
||||
"strum_macros 0.20.1",
|
||||
"sysinfo",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
|
@ -1711,6 +1713,12 @@ version = "0.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.18.0"
|
||||
|
@ -1723,6 +1731,18 @@ dependencies = [
|
|||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.11.11"
|
||||
|
@ -1778,8 +1798,8 @@ checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
|
|||
dependencies = [
|
||||
"heck",
|
||||
"pkg-config",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"strum 0.18.0",
|
||||
"strum_macros 0.18.0",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"version-compare",
|
||||
|
|
|
@ -220,7 +220,7 @@ For Wayland users the `<reserve/>` block is replaced by the exclusive field in `
|
|||
The previous `<window>` block would look like this.
|
||||
|
||||
```xml
|
||||
<window name="main_window" stacking="fg" focusable="false" screen="1" exclusive="true">
|
||||
<window name="main_window" stacking="fg" focusable="false" screen="1" exclusive="true" windowtype="normal">
|
||||
<geometry anchor="top left" x="300px" y="50%" width="25%" height="20px"/>
|
||||
<widget>
|
||||
<main/>
|
||||
|
@ -247,3 +247,10 @@ There are a couple things you can optionally configure on the window itself:
|
|||
The details on how it is actually implemented are left to the compositor.
|
||||
This option is only valid on Wayland.
|
||||
Possible values: `"true"`, `"false"`. Default: `"false"`
|
||||
- `windowtype`: (X11 only) Can be used in determining the decoration, stacking position and other behavior of the window.
|
||||
Possible values:
|
||||
- `"normal"`: indicates that this is a normal, top-level window
|
||||
- `"dock"`: indicates a dock or panel feature
|
||||
- `"toolbar"`: toolbars "torn off" from the main application
|
||||
- `"dialog"`: indicates that this is a dialog window
|
||||
- Default: `"dock"` if reserve is set, else `"normal"`
|
||||
|
|
|
@ -93,7 +93,7 @@ contain are defined. -->
|
|||
|
||||
<windows>
|
||||
<!-- These are the windows -->
|
||||
<window name="bar" screen="0">
|
||||
<window name="bar" screen="0" focusable="true" windowtype="dock">
|
||||
<geometry x="0%" y="0%" width="100%" height="4%"/> <!--Specifies geometry-->
|
||||
<reserve side="top" distance="4%" layer="top"/>
|
||||
<widget>
|
||||
|
|
|
@ -307,7 +307,6 @@ fn initialize_window(
|
|||
window_def: config::EwwWindowDefinition,
|
||||
) -> Result<EwwWindow> {
|
||||
let actual_window_rect = window_def.geometry.get_window_rectangle(monitor_geometry);
|
||||
|
||||
if let Some(window) = display_backend::initialize_window(&window_def, monitor_geometry) {
|
||||
window.set_title(&format!("Eww - {}", window_def.name));
|
||||
let wm_class_name = format!("eww-{}", window_def.name);
|
||||
|
@ -329,7 +328,7 @@ fn initialize_window(
|
|||
gdk_window.set_override_redirect(!window_def.focusable);
|
||||
|
||||
#[cfg(feature = "x11")]
|
||||
display_backend::reserve_space_for(&window, monitor_geometry, window_def.struts)?;
|
||||
display_backend::set_xprops(&window, monitor_geometry, &window_def)?;
|
||||
|
||||
// this should only be required on x11, as waylands layershell should manage the margins properly anways.
|
||||
#[cfg(feature = "x11")]
|
||||
|
@ -344,7 +343,6 @@ fn initialize_window(
|
|||
} else {
|
||||
Err(anyhow!("monitor {} is unavailable", window_def.screen_number.unwrap()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Apply the provided window-positioning rules to the window.
|
||||
|
|
|
@ -1,23 +1,52 @@
|
|||
use super::*;
|
||||
use crate::{ensure_xml_tag_is, value::NumWithUnit, widgets::widget_node};
|
||||
use anyhow::*;
|
||||
use derive_more::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use smart_default::SmartDefault;
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use super::*;
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum EwwWindowType {
|
||||
Dock,
|
||||
Dialog,
|
||||
Toolbar,
|
||||
Normal,
|
||||
}
|
||||
impl FromStr for EwwWindowType {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"dock" => Ok(Self::Dock),
|
||||
"toolbar" => Ok(Self::Toolbar),
|
||||
"dialog" => Ok(Self::Dialog),
|
||||
"normal" => Ok(Self::Normal),
|
||||
x => Err(anyhow!("Unknown windowtype provided '{}'. Possible values are: dock, toolbar, dialog, normal", x)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for EwwWindowType {
|
||||
fn default() -> Self {
|
||||
Self::Normal
|
||||
}
|
||||
}
|
||||
|
||||
/// Full window-definition containing the fully expanded widget tree.
|
||||
/// **Use this** rather than `[RawEwwWindowDefinition]`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EwwWindowDefinition {
|
||||
pub name: WindowName,
|
||||
|
||||
pub geometry: EwwWindowGeometry,
|
||||
pub stacking: WindowStacking,
|
||||
pub screen_number: Option<i32>,
|
||||
pub widget: Box<dyn widget_node::WidgetNode>,
|
||||
pub focusable: bool,
|
||||
|
||||
#[cfg(feature = "x11")]
|
||||
pub window_type: EwwWindowType,
|
||||
|
||||
#[cfg(feature = "x11")]
|
||||
pub struts: StrutDefinition,
|
||||
|
||||
|
@ -35,6 +64,8 @@ impl EwwWindowDefinition {
|
|||
widget: widget_node::generate_generic_widget_node(defs, &HashMap::new(), window.widget)?,
|
||||
focusable: window.focusable,
|
||||
#[cfg(feature = "x11")]
|
||||
window_type: window.window_type,
|
||||
#[cfg(feature = "x11")]
|
||||
struts: window.struts,
|
||||
#[cfg(feature = "wayland")]
|
||||
exclusive: window.exclusive,
|
||||
|
@ -52,6 +83,9 @@ pub struct RawEwwWindowDefinition {
|
|||
pub widget: WidgetUse,
|
||||
pub focusable: bool,
|
||||
|
||||
#[cfg(feature = "x11")]
|
||||
pub window_type: EwwWindowType,
|
||||
|
||||
#[cfg(feature = "x11")]
|
||||
pub struts: StrutDefinition,
|
||||
|
||||
|
@ -78,6 +112,14 @@ impl RawEwwWindowDefinition {
|
|||
Ok(node) => EwwWindowGeometry::from_xml_element(node)?,
|
||||
Err(_) => EwwWindowGeometry::default(),
|
||||
},
|
||||
#[cfg(feature = "x11")]
|
||||
window_type: match xml.attr("windowtype") {
|
||||
Ok(v) => EwwWindowType::from_str(&v)?,
|
||||
Err(_) => match struts {
|
||||
Some(_) => EwwWindowType::Dock,
|
||||
None => Default::default(),
|
||||
},
|
||||
},
|
||||
widget: WidgetUse::from_xml_node(xml.child("widget")?.only_child()?)?,
|
||||
stacking,
|
||||
screen_number,
|
||||
|
|
|
@ -108,7 +108,7 @@ mod platform {
|
|||
|
||||
#[cfg(feature = "x11")]
|
||||
mod platform {
|
||||
use crate::config::{EwwWindowDefinition, Side, StrutDefinition, WindowStacking};
|
||||
use crate::config::{EwwWindowDefinition, EwwWindowType, Side, WindowStacking};
|
||||
use anyhow::*;
|
||||
use gdkx11;
|
||||
use gtk::{self, prelude::*};
|
||||
|
@ -139,9 +139,9 @@ mod platform {
|
|||
Some(window)
|
||||
}
|
||||
|
||||
pub fn reserve_space_for(window: >k::Window, monitor: gdk::Rectangle, strut_def: StrutDefinition) -> Result<()> {
|
||||
pub fn set_xprops(window: >k::Window, monitor: gdk::Rectangle, window_def: &EwwWindowDefinition) -> Result<()> {
|
||||
let backend = X11Backend::new()?;
|
||||
backend.reserve_space_for(window, monitor, strut_def)?;
|
||||
backend.set_xprops_for(window, monitor, window_def)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -159,11 +159,11 @@ mod platform {
|
|||
Ok(X11Backend { conn, root_window: screen.root, atoms })
|
||||
}
|
||||
|
||||
fn reserve_space_for(
|
||||
fn set_xprops_for(
|
||||
&self,
|
||||
window: >k::Window,
|
||||
monitor_rect: gdk::Rectangle,
|
||||
strut_def: StrutDefinition,
|
||||
window_def: &EwwWindowDefinition,
|
||||
) -> Result<()> {
|
||||
let win_id = window
|
||||
.get_window()
|
||||
|
@ -172,6 +172,7 @@ mod platform {
|
|||
.ok()
|
||||
.context("Failed to get x11 window for gtk window")?
|
||||
.get_xid() as u32;
|
||||
let strut_def = window_def.struts;
|
||||
let root_window_geometry = self.conn.get_geometry(self.root_window)?.reply()?;
|
||||
|
||||
let mon_end_x = (monitor_rect.x + monitor_rect.width) as u32 - 1u32;
|
||||
|
@ -217,16 +218,33 @@ mod platform {
|
|||
&strut_list,
|
||||
)?
|
||||
.check()?;
|
||||
self.conn.flush()?;
|
||||
Ok(())
|
||||
|
||||
x11rb::wrapper::ConnectionExt::change_property32(
|
||||
&self.conn,
|
||||
PropMode::REPLACE,
|
||||
win_id,
|
||||
self.atoms._NET_WM_WINDOW_TYPE,
|
||||
self.atoms.ATOM,
|
||||
&[match window_def.window_type {
|
||||
EwwWindowType::Dock => self.atoms._NET_WM_WINDOW_TYPE_DOCK,
|
||||
EwwWindowType::Normal => self.atoms._NET_WM_WINDOW_TYPE_NORMAL,
|
||||
EwwWindowType::Dialog => self.atoms._NET_WM_WINDOW_TYPE_DIALOG,
|
||||
EwwWindowType::Toolbar => self.atoms._NET_WM_WINDOW_TYPE_TOOLBAR,
|
||||
}],
|
||||
)?
|
||||
.check()?;
|
||||
|
||||
self.conn.flush().context("Failed to send requests to X server")
|
||||
}
|
||||
}
|
||||
|
||||
x11rb::atom_manager! {
|
||||
pub AtomCollection: AtomCollectionCookie {
|
||||
_NET_WM_WINDOW_TYPE,
|
||||
_NET_WM_WINDOW_TYPE_NORMAL,
|
||||
_NET_WM_WINDOW_TYPE_DOCK,
|
||||
_NET_WM_WINDOW_TYPE_DIALOG,
|
||||
_NET_WM_WINDOW_TYPE_TOOLBAR,
|
||||
_NET_WM_STATE,
|
||||
_NET_WM_STATE_STICKY,
|
||||
_NET_WM_STATE_ABOVE,
|
||||
|
|
Loading…
Add table
Reference in a new issue