From a697b30223a3bbca941fdd167e7252af89a0bf20 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sun, 18 Jul 2021 12:52:20 -0700 Subject: [PATCH] window: add xsettings support on X11 systems This allows reading xsettings which contain information about both the active theme as well as the DPI. refs: #947 --- Cargo.lock | 8 + docs/config/lua/config/dpi.md | 1 + wezterm-gui/src/termwindow/mod.rs | 3 +- window/Cargo.toml | 2 + window/src/os/x11/connection.rs | 91 +++++-- window/src/os/x11/mod.rs | 1 + window/src/os/x11/window.rs | 14 +- window/src/os/x11/xsettings.rs | 429 ++++++++++++++++++++++++++++++ 8 files changed, 531 insertions(+), 18 deletions(-) create mode 100644 window/src/os/x11/xsettings.rs diff --git a/Cargo.lock b/Cargo.lock index 120df6d5f74..90baf239561 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -513,6 +513,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" + [[package]] name = "cache-padded" version = "1.1.1" @@ -5255,6 +5261,7 @@ dependencies = [ "async-task", "async-trait", "bitflags", + "bytes", "cgl", "clipboard", "clipboard-win", @@ -5269,6 +5276,7 @@ dependencies = [ "gl_generator", "glium", "guillotiere", + "k9", "lazy_static", "libc", "libloading 0.6.7", diff --git a/docs/config/lua/config/dpi.md b/docs/config/lua/config/dpi.md index 2aa25e91b92..5002b4cfd5c 100644 --- a/docs/config/lua/config/dpi.md +++ b/docs/config/lua/config/dpi.md @@ -14,6 +14,7 @@ The default value is system specific: |Windows |Probed from the display |Probed from the display | |X11 |96.0 |96.0 | |X11 (*version 20210314-114017-04b7cedd and later*)|Probed from `Xft.dpi`, fallback to 96.0 |Probed from `Xft.dpi`, fallback to 96.0 | +|X11 (*Since: nightly builds only*)|Reads `Xft/DPI` via xsettings, fallback to `Xft.dpi`, then fallback to 96.0 | same as standard density | |Wayland |96.0 |192.0 | In macOS and Wayland environments there isn't strictly a system DPI value that diff --git a/wezterm-gui/src/termwindow/mod.rs b/wezterm-gui/src/termwindow/mod.rs index bfcf081bc1c..96289152cc4 100644 --- a/wezterm-gui/src/termwindow/mod.rs +++ b/wezterm-gui/src/termwindow/mod.rs @@ -546,7 +546,8 @@ impl TermWindow { self.close_requested(window); Ok(true) } - WindowEvent::AppearanceChanged(_appearance) => { + WindowEvent::AppearanceChanged(appearance) => { + log::debug!("Appearance is now {:?}", appearance); self.config_was_reloaded(); Ok(true) } diff --git a/window/Cargo.toml b/window/Cargo.toml index 8d170f62c46..a1bfd4fd7c0 100644 --- a/window/Cargo.toml +++ b/window/Cargo.toml @@ -11,6 +11,7 @@ build = "build.rs" [dev-dependencies] pretty_env_logger = "0.4" wgpu = "0.9" +k9 = "0.11.0" [build-dependencies] gl_generator = "0.14" @@ -24,6 +25,7 @@ async-io = "1.1" async-task = "4.0" async-trait = "0.1" anyhow = "1.0" +bytes = "1.0" config = { path = "../config" } color-types = { path = "../color-types" } thiserror = "1.0" diff --git a/window/src/os/x11/connection.rs b/window/src/os/x11/connection.rs index 08b28989ef6..c0cc52f29b2 100644 --- a/window/src/os/x11/connection.rs +++ b/window/src/os/x11/connection.rs @@ -1,8 +1,10 @@ use super::keyboard::Keyboard; use crate::connection::ConnectionOps; use crate::os::x11::window::XWindowInner; +use crate::os::x11::xsettings::*; use crate::os::Connection; use crate::spawn::*; +use crate::Appearance; use anyhow::{anyhow, bail, Context as _}; use mio::unix::EventedFd; use mio::{Evented, Events, Poll, PollOpt, Ready, Token}; @@ -16,6 +18,7 @@ use xcb_util::ffi::keysyms::{xcb_key_symbols_alloc, xcb_key_symbols_free, xcb_ke pub struct XConnection { pub conn: xcb_util::ewmh::Connection, default_dpi: RefCell, + pub(crate) xsettings: RefCell, pub screen_num: i32, pub root: xcb::xproto::Window, pub keyboard: Keyboard, @@ -28,6 +31,9 @@ pub struct XConnection { pub atom_targets: xcb::Atom, pub atom_clipboard: xcb::Atom, pub atom_gtk_edge_constraints: xcb::Atom, + pub atom_xsettings_selection: xcb::Atom, + pub atom_xsettings_settings: xcb::Atom, + pub atom_manager: xcb::Atom, keysyms: *mut xcb_key_symbols_t, pub(crate) xrm: RefCell>, pub(crate) windows: RefCell>>>, @@ -150,6 +156,27 @@ impl ConnectionOps for XConnection { *self.default_dpi.borrow() } + fn get_appearance(&self) -> Appearance { + if let Some(XSetting::String(name)) = self.xsettings.borrow().get("Net/ThemeName") { + let lower = name.to_ascii_lowercase(); + match lower.as_str() { + "highcontrast" => Appearance::LightHighContrast, + "highcontrastinverse" => Appearance::DarkHighContrast, + "adwaita" => Appearance::Light, + "adwaita-dark" => Appearance::Dark, + lower => { + if lower.contains("dark") { + Appearance::Dark + } else { + Appearance::Light + } + } + } + } else { + Appearance::Dark + } + } + fn run_message_loop(&self) -> anyhow::Result<()> { self.conn.flush(); @@ -195,19 +222,42 @@ impl ConnectionOps for XConnection { } } -impl XConnection { - pub(crate) fn update_xrm(&self) { - let xrm = crate::x11::xrm::parse_root_resource_manager(&self.conn, self.root) - .unwrap_or(HashMap::new()); - let dpi = xrm - .get("Xft.dpi") +fn compute_default_dpi(xrm: &HashMap, xsettings: &XSettingsMap) -> f64 { + if let Some(XSetting::Integer(dpi)) = xsettings.get("Xft/DPI") { + *dpi as f64 / 1024.0 + } else { + xrm.get("Xft.dpi") .as_ref() .map(|s| s.as_str()) .unwrap_or("96") .parse::() - .unwrap_or(crate::DEFAULT_DPI); + .unwrap_or(crate::DEFAULT_DPI) + } +} + +impl XConnection { + pub(crate) fn update_xrm(&self) { + match read_xsettings( + &self.conn, + self.atom_xsettings_selection, + self.atom_xsettings_settings, + ) { + Ok(settings) => { + if *self.xsettings.borrow() != settings { + log::trace!("xsettings changed to {:?}", settings); + *self.xsettings.borrow_mut() = settings; + } + } + Err(err) => { + log::error!("error reading xsettings: {:#}", err); + } + } + let xrm = crate::x11::xrm::parse_root_resource_manager(&self.conn, self.root) + .unwrap_or(HashMap::new()); *self.xrm.borrow_mut() = xrm; + + let dpi = compute_default_dpi(&self.xrm.borrow(), &self.xsettings.borrow()); *self.default_dpi.borrow_mut() = dpi; } @@ -297,6 +347,16 @@ impl XConnection { let atom_gtk_edge_constraints = xcb::intern_atom(&conn, false, "_GTK_EDGE_CONSTRAINTS") .get_reply()? .atom(); + let atom_xsettings_selection = + xcb::intern_atom(&conn, false, &format!("_XSETTINGS_S{}", screen_num)) + .get_reply()? + .atom(); + let atom_xsettings_settings = xcb::intern_atom(&conn, false, "_XSETTINGS_SETTINGS") + .get_reply()? + .atom(); + let atom_manager = xcb::intern_atom(&conn, false, "MANAGER") + .get_reply()? + .atom(); let keysyms = unsafe { xcb_key_symbols_alloc((*conn).get_raw_conn()) }; @@ -349,18 +409,16 @@ impl XConnection { let xrm = crate::x11::xrm::parse_root_resource_manager(&conn, root).unwrap_or(HashMap::new()); - let default_dpi = RefCell::new( - xrm.get("Xft.dpi") - .as_ref() - .map(|s| s.as_str()) - .unwrap_or("96") - .parse::() - .unwrap_or(crate::DEFAULT_DPI), - ); + + let xsettings = read_xsettings(&conn, atom_xsettings_selection, atom_xsettings_settings)?; + log::trace!("xsettings are {:?}", xsettings); + + let default_dpi = RefCell::new(compute_default_dpi(&xrm, &xsettings)); let conn = XConnection { conn, default_dpi, + xsettings: RefCell::new(xsettings), cursor_font_id, screen_num, root, @@ -368,6 +426,9 @@ impl XConnection { atom_protocols, atom_clipboard, atom_gtk_edge_constraints, + atom_xsettings_selection, + atom_xsettings_settings, + atom_manager, atom_delete, keysyms, keyboard, diff --git a/window/src/os/x11/mod.rs b/window/src/os/x11/mod.rs index d90a4bc1694..49dd53d1d5e 100644 --- a/window/src/os/x11/mod.rs +++ b/window/src/os/x11/mod.rs @@ -4,6 +4,7 @@ pub mod cursor; pub mod keyboard; pub mod window; pub mod xrm; +pub mod xsettings; pub use self::window::*; pub use connection::*; diff --git a/window/src/os/x11/window.rs b/window/src/os/x11/window.rs index baa8329af11..6ebc0254f32 100644 --- a/window/src/os/x11/window.rs +++ b/window/src/os/x11/window.rs @@ -4,8 +4,8 @@ use crate::connection::ConnectionOps; use crate::os::xkeysyms; use crate::os::{Connection, Window}; use crate::{ - Clipboard, Dimensions, MouseButtons, MouseCursor, MouseEvent, MouseEventKind, MousePress, - Point, ScreenPoint, WindowDecorations, WindowEvent, WindowEventSender, WindowOps, + Appearance, Clipboard, Dimensions, MouseButtons, MouseCursor, MouseEvent, MouseEventKind, + MousePress, Point, ScreenPoint, WindowDecorations, WindowEvent, WindowEventSender, WindowOps, }; use anyhow::{anyhow, Context as _}; use async_trait::async_trait; @@ -61,6 +61,7 @@ pub(crate) struct XWindowInner { cursors: CursorInfo, copy_and_paste: CopyAndPaste, config: ConfigHandle, + appearance: Appearance, } impl Drop for XWindowInner { @@ -319,6 +320,12 @@ impl XWindowInner { // when running under gnome. conn.update_xrm(); self.check_dpi_and_synthesize_resize(); + let appearance = conn.get_appearance(); + if appearance != self.appearance { + self.appearance = appearance; + self.events + .dispatch(WindowEvent::AppearanceChanged(appearance)); + } } } xcb::FOCUS_IN => { @@ -735,7 +742,10 @@ impl XWindow { events.assign_window(Window::X11(XWindow::from_id(window_id))); + let appearance = conn.get_appearance(); + Arc::new(Mutex::new(XWindowInner { + appearance, window_id, conn: Rc::downgrade(&conn), events, diff --git a/window/src/os/x11/xsettings.rs b/window/src/os/x11/xsettings.rs new file mode 100644 index 00000000000..8761b8cd4dd --- /dev/null +++ b/window/src/os/x11/xsettings.rs @@ -0,0 +1,429 @@ +/// This module parses xsettings data. +/// The data format is slightly incorrectly documented here: +/// +/// I looked at the libxsettings-client sources to verify the behavior; +/// there is a discrepancy in the representation of string setting lengths, +/// but otherwise it seems to parse the data from my 2021 gnome window environment. +use bytes::Buf; +use std::collections::BTreeMap; + +pub type XSettingsMap = BTreeMap; + +#[derive(Debug, PartialEq, Eq)] +pub enum XSetting { + Integer(i32), + String(String), + Color(u16, u16, u16, u16), +} + +fn read_xsettings_grabbed( + conn: &xcb::Connection, + atom_xsettings_selection: xcb::Atom, + atom_xsettings_settings: xcb::Atom, +) -> anyhow::Result { + let manager = xcb::get_selection_owner(&conn, atom_xsettings_selection) + .get_reply()? + .owner(); + + let reply = xcb::xproto::get_property( + &conn, + false, + manager, + atom_xsettings_settings, + atom_xsettings_settings, + 0, + u32::max_value(), + ) + .get_reply()?; + + anyhow::ensure!(reply.format() == 8); + + parse_xsettings(reply.value::()) +} + +pub fn read_xsettings( + conn: &xcb::Connection, + atom_xsettings_selection: xcb::Atom, + atom_xsettings_settings: xcb::Atom, +) -> anyhow::Result> { + xcb::xproto::grab_server(conn).request_check()?; + let res = read_xsettings_grabbed(conn, atom_xsettings_selection, atom_xsettings_settings); + xcb::xproto::ungrab_server(conn).request_check()?; + res +} + +pub fn parse_xsettings(data: &[u8]) -> anyhow::Result { + anyhow::ensure!(data.len() > 0); + + let mut settings = BTreeMap::new(); + + let mut buf = data; + let is_big_endian = buf.get_u8() != 0; + + fn get_u8(buf: &mut BUF) -> anyhow::Result { + anyhow::ensure!(buf.remaining() >= 1); + Ok(buf.get_u8()) + } + fn get_u16(buf: &mut BUF, is_big_endian: bool) -> anyhow::Result { + anyhow::ensure!(buf.remaining() >= 2); + Ok(if is_big_endian { + buf.get_u16() + } else { + buf.get_u16_le() + }) + } + fn get_u32(buf: &mut BUF, is_big_endian: bool) -> anyhow::Result { + anyhow::ensure!(buf.remaining() >= 4); + Ok(if is_big_endian { + buf.get_u32() + } else { + buf.get_u32_le() + }) + } + fn get_i32(buf: &mut BUF, is_big_endian: bool) -> anyhow::Result { + anyhow::ensure!(buf.remaining() >= 4); + Ok(if is_big_endian { + buf.get_i32() + } else { + buf.get_i32_le() + }) + } + fn advance(buf: &mut BUF, n: usize) -> anyhow::Result<()> { + anyhow::ensure!(buf.remaining() >= n); + buf.advance(n); + Ok(()) + } + + advance(&mut buf, 3)?; + let _serial = get_u32(&mut buf, is_big_endian)?; + let num_settings = get_u32(&mut buf, is_big_endian)? as usize; + + fn pad(len: usize) -> usize { + (len + 3) & !3 + } + + for _ in 0..num_settings { + let setting_type = get_u8(&mut buf)?; + advance(&mut buf, 1)?; + let name_len = get_u16(&mut buf, is_big_endian)? as usize; + let padded_name_len = pad(name_len); + anyhow::ensure!( + buf.remaining() >= padded_name_len, + "name_len is {} (pad: {}) but buffer has {} remaining", + name_len, + padded_name_len, + buf.remaining() + ); + let name = String::from_utf8(buf.chunk()[..name_len].to_vec())?; + buf.advance(padded_name_len); + + let _last_change_serial = get_u32(&mut buf, is_big_endian)?; + + let value = match setting_type { + 0 => XSetting::Integer(get_i32(&mut buf, is_big_endian)?), + 1 => { + // Note that the xsettings-latest spec indicates that this + // length is a u16, but that fails to parse real data, + // and libxsettings-client treats it as u32, so we do too. + let s_len = get_u32(&mut buf, is_big_endian)? as usize; + let padded_s_len = pad(s_len); + anyhow::ensure!( + buf.remaining() >= padded_s_len, + "s_len is {} (pad: {}) but buffer has {} remaining", + s_len, + padded_s_len, + buf.remaining() + ); + let s = String::from_utf8(buf.chunk()[..s_len].to_vec())?; + buf.advance(padded_s_len); + + XSetting::String(s) + } + 2 => { + let red = get_u16(&mut buf, is_big_endian)?; + let green = get_u16(&mut buf, is_big_endian)?; + let blue = get_u16(&mut buf, is_big_endian)?; + let alpha = get_u16(&mut buf, is_big_endian)?; + XSetting::Color(red, green, blue, alpha) + } + n => anyhow::bail!("invalid setting type {}, expected, 0, 1 or 2", n), + }; + settings.insert(name, value); + } + + Ok(settings) +} + +mod test { + #[test] + fn test_parse_xsettings() { + let data = [ + 0, 0, 0, 0, 152, 0, 0, 0, 53, 0, 0, 0, 0, 0, 15, 0, 71, 100, 107, 47, 85, 110, 115, 99, + 97, 108, 101, 100, 68, 80, 73, 0, 0, 0, 0, 0, 0, 128, 1, 0, 0, 0, 22, 0, 71, 116, 107, + 47, 82, 101, 99, 101, 110, 116, 70, 105, 108, 101, 115, 69, 110, 97, 98, 108, 101, 100, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 19, 0, 71, 116, 107, 47, 67, 117, 114, 115, 111, + 114, 84, 104, 101, 109, 101, 83, 105, 122, 101, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 23, + 0, 71, 116, 107, 47, 83, 104, 111, 119, 73, 110, 112, 117, 116, 77, 101, 116, 104, 111, + 100, 77, 101, 110, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 78, 101, 116, 47, 68, + 110, 100, 68, 114, 97, 103, 84, 104, 114, 101, 115, 104, 111, 108, 100, 0, 0, 0, 0, 8, + 0, 0, 0, 0, 0, 18, 0, 71, 116, 107, 47, 84, 105, 109, 101, 111, 117, 116, 73, 110, 105, + 116, 105, 97, 108, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 1, 0, 20, 0, 71, 116, 107, 47, 68, + 101, 99, 111, 114, 97, 116, 105, 111, 110, 76, 97, 121, 111, 117, 116, 0, 0, 0, 0, 10, + 0, 0, 0, 109, 101, 110, 117, 58, 99, 108, 111, 115, 101, 0, 0, 0, 0, 13, 0, 88, 102, + 116, 47, 65, 110, 116, 105, 97, 108, 105, 97, 115, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 19, 0, 78, 101, 116, 47, 67, 117, 114, 115, 111, 114, 66, 108, 105, 110, 107, 84, + 105, 109, 101, 0, 0, 0, 0, 0, 176, 4, 0, 0, 1, 0, 12, 0, 71, 116, 107, 47, 73, 77, 77, + 111, 100, 117, 108, 101, 0, 0, 0, 0, 21, 0, 0, 0, 103, 116, 107, 45, 105, 109, 45, 99, + 111, 110, 116, 101, 120, 116, 45, 115, 105, 109, 112, 108, 101, 0, 0, 0, 0, 0, 21, 0, + 71, 116, 107, 47, 83, 104, 101, 108, 108, 83, 104, 111, 119, 115, 68, 101, 115, 107, + 116, 111, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 88, 102, 116, 47, 72, 105, + 110, 116, 105, 110, 103, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 13, 0, 88, 102, 116, 47, 72, + 105, 110, 116, 83, 116, 121, 108, 101, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 104, 105, 110, + 116, 115, 108, 105, 103, 104, 116, 0, 0, 0, 0, 14, 0, 71, 116, 107, 47, 77, 101, 110, + 117, 73, 109, 97, 103, 101, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 71, 116, + 107, 47, 84, 105, 109, 101, 111, 117, 116, 82, 101, 112, 101, 97, 116, 0, 0, 0, 0, 0, + 0, 0, 20, 0, 0, 0, 0, 0, 22, 0, 71, 116, 107, 47, 69, 110, 97, 98, 108, 101, 80, 114, + 105, 109, 97, 114, 121, 80, 97, 115, 116, 101, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 18, + 0, 71, 116, 107, 47, 75, 101, 121, 110, 97, 118, 85, 115, 101, 67, 97, 114, 101, 116, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 71, 116, 107, 47, 83, 104, 101, 108, 108, + 83, 104, 111, 119, 115, 65, 112, 112, 77, 101, 110, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19, 0, 71, 116, 107, 47, 67, 97, 110, 67, 104, 97, 110, 103, 101, 65, 99, 99, + 101, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 12, 0, 71, 116, 107, 47, 70, 111, 110, + 116, 78, 97, 109, 101, 0, 0, 0, 0, 12, 0, 0, 0, 67, 97, 110, 116, 97, 114, 101, 108, + 108, 32, 49, 49, 1, 0, 13, 0, 78, 101, 116, 47, 84, 104, 101, 109, 101, 78, 97, 109, + 101, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 65, 100, 119, 97, 105, 116, 97, 45, 100, 97, + 114, 107, 0, 0, 19, 0, 78, 101, 116, 47, 68, 111, 117, 98, 108, 101, 67, 108, 105, 99, + 107, 84, 105, 109, 101, 0, 0, 0, 0, 0, 144, 1, 0, 0, 0, 0, 20, 0, 71, 116, 107, 47, 68, + 105, 97, 108, 111, 103, 115, 85, 115, 101, 72, 101, 97, 100, 101, 114, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 23, 0, 71, 100, 107, 47, 87, 105, 110, 100, 111, 119, 83, 99, 97, 108, + 105, 110, 103, 70, 97, 99, 116, 111, 114, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 16, 0, 71, + 116, 107, 47, 84, 111, 111, 108, 98, 97, 114, 83, 116, 121, 108, 101, 0, 0, 0, 0, 10, + 0, 0, 0, 98, 111, 116, 104, 45, 104, 111, 114, 105, 122, 0, 0, 1, 0, 16, 0, 71, 116, + 107, 47, 75, 101, 121, 84, 104, 101, 109, 101, 78, 97, 109, 101, 0, 0, 0, 0, 7, 0, 0, + 0, 68, 101, 102, 97, 117, 108, 116, 0, 0, 0, 15, 0, 78, 101, 116, 47, 67, 117, 114, + 115, 111, 114, 66, 108, 105, 110, 107, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 0, 71, 116, + 107, 47, 73, 77, 80, 114, 101, 101, 100, 105, 116, 83, 116, 121, 108, 101, 0, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 99, 97, 108, 108, 98, 97, 99, 107, 0, 0, 20, 0, 71, 116, 107, 47, 69, + 110, 97, 98, 108, 101, 65, 110, 105, 109, 97, 116, 105, 111, 110, 115, 0, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 7, 0, 88, 102, 116, 47, 68, 80, 73, 0, 0, 0, 0, 0, 0, 128, 1, 0, 1, 0, + 19, 0, 71, 116, 107, 47, 67, 117, 114, 115, 111, 114, 84, 104, 101, 109, 101, 78, 97, + 109, 101, 0, 0, 0, 0, 0, 7, 0, 0, 0, 65, 100, 119, 97, 105, 116, 97, 0, 1, 0, 19, 0, + 71, 116, 107, 47, 84, 111, 111, 108, 98, 97, 114, 73, 99, 111, 110, 83, 105, 122, 101, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 108, 97, 114, 103, 101, 0, 0, 0, 1, 0, 17, 0, 71, 116, 107, + 47, 73, 77, 83, 116, 97, 116, 117, 115, 83, 116, 121, 108, 101, 0, 0, 0, 0, 0, 0, 0, 8, + 0, 0, 0, 99, 97, 108, 108, 98, 97, 99, 107, 0, 0, 21, 0, 71, 116, 107, 47, 82, 101, 99, + 101, 110, 116, 70, 105, 108, 101, 115, 77, 97, 120, 65, 103, 101, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 1, 0, 11, 0, 71, 116, 107, 47, 77, 111, 100, 117, 108, 101, 115, 0, + 0, 0, 0, 0, 33, 0, 0, 0, 99, 97, 110, 98, 101, 114, 114, 97, 45, 103, 116, 107, 45, + 109, 111, 100, 117, 108, 101, 58, 112, 107, 45, 103, 116, 107, 45, 109, 111, 100, 117, + 108, 101, 0, 0, 0, 1, 0, 15, 0, 71, 116, 107, 47, 67, 111, 108, 111, 114, 83, 99, 104, + 101, 109, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 71, 116, 107, 47, 65, 117, 116, + 111, 77, 110, 101, 109, 111, 110, 105, 99, 115, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 16, 0, 71, 116, 107, 47, 77, 101, 110, 117, 66, 97, 114, 65, 99, 99, 101, 108, 0, 0, 0, + 0, 3, 0, 0, 0, 70, 49, 48, 0, 1, 0, 21, 0, 78, 101, 116, 47, 70, 97, 108, 108, 98, 97, + 99, 107, 73, 99, 111, 110, 84, 104, 101, 109, 101, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, + 103, 110, 111, 109, 101, 0, 0, 0, 1, 0, 16, 0, 71, 116, 107, 47, 67, 111, 108, 111, + 114, 80, 97, 108, 101, 116, 116, 101, 0, 0, 0, 0, 148, 0, 0, 0, 98, 108, 97, 99, 107, + 58, 119, 104, 105, 116, 101, 58, 103, 114, 97, 121, 53, 48, 58, 114, 101, 100, 58, 112, + 117, 114, 112, 108, 101, 58, 98, 108, 117, 101, 58, 108, 105, 103, 104, 116, 32, 98, + 108, 117, 101, 58, 103, 114, 101, 101, 110, 58, 121, 101, 108, 108, 111, 119, 58, 111, + 114, 97, 110, 103, 101, 58, 108, 97, 118, 101, 110, 100, 101, 114, 58, 98, 114, 111, + 119, 110, 58, 103, 111, 108, 100, 101, 110, 114, 111, 100, 52, 58, 100, 111, 100, 103, + 101, 114, 32, 98, 108, 117, 101, 58, 112, 105, 110, 107, 58, 108, 105, 103, 104, 116, + 32, 103, 114, 101, 101, 110, 58, 103, 114, 97, 121, 49, 48, 58, 103, 114, 97, 121, 51, + 48, 58, 103, 114, 97, 121, 55, 53, 58, 103, 114, 97, 121, 57, 48, 0, 0, 20, 0, 71, 116, + 107, 47, 79, 118, 101, 114, 108, 97, 121, 83, 99, 114, 111, 108, 108, 105, 110, 103, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 0, 21, 0, 78, 101, 116, 47, 69, 110, 97, 98, 108, 101, 69, 118, + 101, 110, 116, 83, 111, 117, 110, 100, 115, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, + 0, 78, 101, 116, 47, 73, 99, 111, 110, 84, 104, 101, 109, 101, 78, 97, 109, 101, 0, 0, + 0, 0, 0, 0, 0, 7, 0, 0, 0, 65, 100, 119, 97, 105, 116, 97, 0, 0, 0, 19, 0, 71, 116, + 107, 47, 83, 104, 111, 119, 85, 110, 105, 99, 111, 100, 101, 77, 101, 110, 117, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 16, 0, 71, 116, 107, 47, 83, 101, 115, 115, 105, 111, 110, + 66, 117, 115, 73, 100, 0, 0, 0, 0, 32, 0, 0, 0, 54, 97, 52, 98, 56, 49, 51, 102, 53, + 50, 54, 54, 99, 99, 101, 48, 54, 57, 49, 53, 57, 53, 99, 101, 57, 51, 51, 52, 54, 100, + 102, 100, 0, 0, 22, 0, 71, 116, 107, 47, 67, 117, 114, 115, 111, 114, 66, 108, 105, + 110, 107, 84, 105, 109, 101, 111, 117, 116, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, + 71, 116, 107, 47, 66, 117, 116, 116, 111, 110, 73, 109, 97, 103, 101, 115, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 22, 0, 71, 116, 107, 47, 84, 105, 116, 108, 101, 98, 97, 114, 82, + 105, 103, 104, 116, 67, 108, 105, 99, 107, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 101, 110, + 117, 1, 0, 18, 0, 78, 101, 116, 47, 83, 111, 117, 110, 100, 84, 104, 101, 109, 101, 78, + 97, 109, 101, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 95, 95, 99, 117, 115, 116, 111, 109, 0, 0, + 29, 0, 78, 101, 116, 47, 69, 110, 97, 98, 108, 101, 73, 110, 112, 117, 116, 70, 101, + 101, 100, 98, 97, 99, 107, 83, 111, 117, 110, 100, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 23, 0, 71, 116, 107, 47, 84, 105, 116, 108, 101, 98, 97, 114, 68, 111, 117, + 98, 108, 101, 67, 108, 105, 99, 107, 0, 0, 0, 0, 0, 15, 0, 0, 0, 116, 111, 103, 103, + 108, 101, 45, 109, 97, 120, 105, 109, 105, 122, 101, 0, 1, 0, 8, 0, 88, 102, 116, 47, + 82, 71, 66, 65, 0, 0, 0, 0, 4, 0, 0, 0, 110, 111, 110, 101, 1, 0, 23, 0, 71, 116, 107, + 47, 84, 105, 116, 108, 101, 98, 97, 114, 77, 105, 100, 100, 108, 101, 67, 108, 105, 99, + 107, 0, 0, 0, 0, 0, 4, 0, 0, 0, 110, 111, 110, 101, + ]; + + let settings = super::parse_xsettings(&data).unwrap(); + k9::snapshot!( + settings, + r#" +{ + "Gdk/UnscaledDPI": Integer( + 98304, + ), + "Gdk/WindowScalingFactor": Integer( + 1, + ), + "Gtk/AutoMnemonics": Integer( + 1, + ), + "Gtk/ButtonImages": Integer( + 0, + ), + "Gtk/CanChangeAccels": Integer( + 0, + ), + "Gtk/ColorPalette": String( + "black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90", + ), + "Gtk/ColorScheme": String( + "", + ), + "Gtk/CursorBlinkTimeout": Integer( + 10, + ), + "Gtk/CursorThemeName": String( + "Adwaita", + ), + "Gtk/CursorThemeSize": Integer( + 24, + ), + "Gtk/DecorationLayout": String( + "menu:close", + ), + "Gtk/DialogsUseHeader": Integer( + 1, + ), + "Gtk/EnableAnimations": Integer( + 1, + ), + "Gtk/EnablePrimaryPaste": Integer( + 1, + ), + "Gtk/FontName": String( + "Cantarell 11", + ), + "Gtk/IMModule": String( + "gtk-im-context-simple", + ), + "Gtk/IMPreeditStyle": String( + "callback", + ), + "Gtk/IMStatusStyle": String( + "callback", + ), + "Gtk/KeyThemeName": String( + "Default", + ), + "Gtk/KeynavUseCaret": Integer( + 0, + ), + "Gtk/MenuBarAccel": String( + "F10", + ), + "Gtk/MenuImages": Integer( + 0, + ), + "Gtk/Modules": String( + "canberra-gtk-module:pk-gtk-module", + ), + "Gtk/OverlayScrolling": Integer( + 1, + ), + "Gtk/RecentFilesEnabled": Integer( + 1, + ), + "Gtk/RecentFilesMaxAge": Integer( + -1, + ), + "Gtk/SessionBusId": String( + "6a4b813f5266cce0691595ce93346dfd", + ), + "Gtk/ShellShowsAppMenu": Integer( + 0, + ), + "Gtk/ShellShowsDesktop": Integer( + 0, + ), + "Gtk/ShowInputMethodMenu": Integer( + 0, + ), + "Gtk/ShowUnicodeMenu": Integer( + 0, + ), + "Gtk/TimeoutInitial": Integer( + 200, + ), + "Gtk/TimeoutRepeat": Integer( + 20, + ), + "Gtk/TitlebarDoubleClick": String( + "toggle-maximize", + ), + "Gtk/TitlebarMiddleClick": String( + "none", + ), + "Gtk/TitlebarRightClick": String( + "menu", + ), + "Gtk/ToolbarIconSize": String( + "large", + ), + "Gtk/ToolbarStyle": String( + "both-horiz", + ), + "Net/CursorBlink": Integer( + 1, + ), + "Net/CursorBlinkTime": Integer( + 1200, + ), + "Net/DndDragThreshold": Integer( + 8, + ), + "Net/DoubleClickTime": Integer( + 400, + ), + "Net/EnableEventSounds": Integer( + 1, + ), + "Net/EnableInputFeedbackSounds": Integer( + 0, + ), + "Net/FallbackIconTheme": String( + "gnome", + ), + "Net/IconThemeName": String( + "Adwaita", + ), + "Net/SoundThemeName": String( + "__custom", + ), + "Net/ThemeName": String( + "Adwaita-dark", + ), + "Xft/Antialias": Integer( + 1, + ), + "Xft/DPI": Integer( + 98304, + ), + "Xft/HintStyle": String( + "hintslight", + ), + "Xft/Hinting": Integer( + 1, + ), + "Xft/RGBA": String( + "none", + ), +} +"# + ); + } +}