mirror of
https://github.com/wez/wezterm.git
synced 2024-11-27 02:25:28 +03:00
window: allow window layer to hold per-window config
This is to allow for eg: hotkey to change window decorations (https://wezfurlong.org/wezterm/config/lua/window/set_config_overrides.html) So far only macos actually keeps a per-window config. Hopefully this still compiles for windows and x11.
This commit is contained in:
parent
a5bc89e6d3
commit
cfed798e79
@ -238,6 +238,7 @@ impl WindowCallbacks for TermWindow {
|
||||
let clipboard_contents = Arc::clone(&self.clipboard_contents);
|
||||
let dimensions = self.dimensions.clone();
|
||||
let mux_window_id = self.mux_window_id;
|
||||
let config = self.config.clone();
|
||||
|
||||
let guts = Box::new(Self {
|
||||
window: None,
|
||||
@ -287,6 +288,7 @@ impl WindowCallbacks for TermWindow {
|
||||
dimensions.pixel_width,
|
||||
dimensions.pixel_height,
|
||||
guts,
|
||||
Some(&crate::window_config::ConfigInstance::new(config)),
|
||||
)?;
|
||||
|
||||
Self::apply_icon(&window)?;
|
||||
@ -492,6 +494,7 @@ impl TermWindow {
|
||||
last_blink_paint: Instant::now(),
|
||||
last_status_call: Instant::now(),
|
||||
}),
|
||||
Some(&crate::window_config::ConfigInstance::new(config)),
|
||||
)?;
|
||||
|
||||
Self::apply_icon(&window)?;
|
||||
@ -755,7 +758,7 @@ impl TermWindow {
|
||||
self.apply_scale_change(&dimensions, self.fonts.get_font_scale());
|
||||
self.apply_dimensions(&dimensions, Some(cell_dims));
|
||||
if let Some(window) = self.window.as_ref() {
|
||||
window.config_did_change();
|
||||
window.config_did_change(&crate::window_config::ConfigInstance::new(config));
|
||||
window.invalidate();
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,43 @@
|
||||
use ::window::configuration::WindowConfiguration;
|
||||
use config::configuration;
|
||||
use config::{configuration, ConfigHandle};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// An instance that always returns the global configuration values
|
||||
pub struct ConfigBridge;
|
||||
|
||||
impl WindowConfiguration for ConfigBridge {
|
||||
/// Returns the config from the given config handle
|
||||
pub struct ConfigInstance(pub ConfigHandle);
|
||||
|
||||
impl ConfigInstance {
|
||||
pub fn new(h: ConfigHandle) -> Arc<dyn WindowConfiguration + Send + Sync> {
|
||||
let s = Self(h);
|
||||
Arc::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowConfiguration for ConfigInstance {
|
||||
fn use_ime(&self) -> bool {
|
||||
configuration().use_ime
|
||||
self.0.use_ime
|
||||
}
|
||||
|
||||
fn use_dead_keys(&self) -> bool {
|
||||
configuration().use_dead_keys
|
||||
self.0.use_dead_keys
|
||||
}
|
||||
|
||||
fn send_composed_key_when_left_alt_is_pressed(&self) -> bool {
|
||||
configuration().send_composed_key_when_left_alt_is_pressed
|
||||
self.0.send_composed_key_when_left_alt_is_pressed
|
||||
}
|
||||
|
||||
fn send_composed_key_when_right_alt_is_pressed(&self) -> bool {
|
||||
configuration().send_composed_key_when_right_alt_is_pressed
|
||||
self.0.send_composed_key_when_right_alt_is_pressed
|
||||
}
|
||||
|
||||
fn enable_wayland(&self) -> bool {
|
||||
configuration().enable_wayland
|
||||
self.0.enable_wayland
|
||||
}
|
||||
|
||||
fn prefer_egl(&self) -> bool {
|
||||
configuration().prefer_egl
|
||||
self.0.prefer_egl
|
||||
}
|
||||
|
||||
fn prefer_swrast(&self) -> bool {
|
||||
@ -38,18 +50,64 @@ impl WindowConfiguration for ConfigBridge {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
configuration().front_end == config::FrontEndSelection::Software
|
||||
self.0.front_end == config::FrontEndSelection::Software
|
||||
}
|
||||
|
||||
fn native_macos_fullscreen_mode(&self) -> bool {
|
||||
configuration().native_macos_fullscreen_mode
|
||||
self.0.native_macos_fullscreen_mode
|
||||
}
|
||||
|
||||
fn window_background_opacity(&self) -> f32 {
|
||||
configuration().window_background_opacity
|
||||
self.0.window_background_opacity
|
||||
}
|
||||
|
||||
fn decorations(&self) -> ::window::WindowDecorations {
|
||||
configuration().window_decorations
|
||||
self.0.window_decorations
|
||||
}
|
||||
}
|
||||
|
||||
fn global() -> ConfigInstance {
|
||||
ConfigInstance(configuration())
|
||||
}
|
||||
|
||||
impl WindowConfiguration for ConfigBridge {
|
||||
fn use_ime(&self) -> bool {
|
||||
global().use_ime()
|
||||
}
|
||||
|
||||
fn use_dead_keys(&self) -> bool {
|
||||
global().use_dead_keys()
|
||||
}
|
||||
|
||||
fn send_composed_key_when_left_alt_is_pressed(&self) -> bool {
|
||||
global().send_composed_key_when_left_alt_is_pressed()
|
||||
}
|
||||
|
||||
fn send_composed_key_when_right_alt_is_pressed(&self) -> bool {
|
||||
global().send_composed_key_when_right_alt_is_pressed()
|
||||
}
|
||||
|
||||
fn enable_wayland(&self) -> bool {
|
||||
global().enable_wayland()
|
||||
}
|
||||
|
||||
fn prefer_egl(&self) -> bool {
|
||||
global().prefer_egl()
|
||||
}
|
||||
|
||||
fn prefer_swrast(&self) -> bool {
|
||||
global().prefer_swrast()
|
||||
}
|
||||
|
||||
fn native_macos_fullscreen_mode(&self) -> bool {
|
||||
global().native_macos_fullscreen_mode()
|
||||
}
|
||||
|
||||
fn window_background_opacity(&self) -> f32 {
|
||||
global().window_background_opacity()
|
||||
}
|
||||
|
||||
fn decorations(&self) -> ::window::WindowDecorations {
|
||||
global().decorations()
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ async fn spawn_window() -> Result<(), Box<dyn std::error::Error>> {
|
||||
allow_close: false,
|
||||
cursor_pos: Point::new(100, 200),
|
||||
}),
|
||||
None,
|
||||
)?;
|
||||
|
||||
eprintln!("before show");
|
||||
|
@ -170,6 +170,7 @@ fn spawn_window() -> anyhow::Result<()> {
|
||||
cursor_pos: Point::new(100, 200),
|
||||
gl: None,
|
||||
}),
|
||||
None,
|
||||
)?;
|
||||
|
||||
win.show();
|
||||
|
@ -55,11 +55,13 @@ lazy_static::lazy_static! {
|
||||
static ref CONFIG: Mutex<Arc<dyn WindowConfiguration + Send + Sync>> = default_config();
|
||||
}
|
||||
|
||||
pub(crate) fn config() -> Arc<dyn WindowConfiguration + Send + Sync> {
|
||||
pub type WindowConfigHandle = Arc<dyn WindowConfiguration + Send + Sync>;
|
||||
|
||||
pub(crate) fn config() -> WindowConfigHandle {
|
||||
Arc::clone(&CONFIG.lock().unwrap())
|
||||
}
|
||||
|
||||
fn default_config() -> Mutex<Arc<dyn WindowConfiguration + Send + Sync>> {
|
||||
fn default_config() -> Mutex<WindowConfigHandle> {
|
||||
struct DefConfig;
|
||||
impl WindowConfiguration for DefConfig {}
|
||||
Mutex::new(Arc::new(DefConfig))
|
||||
|
@ -8,7 +8,7 @@ pub mod os;
|
||||
mod spawn;
|
||||
mod timerlist;
|
||||
|
||||
use configuration::config;
|
||||
use configuration::{config, WindowConfigHandle};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const DEFAULT_DPI: f64 = 72.0;
|
||||
@ -204,7 +204,7 @@ pub trait WindowOps {
|
||||
Future::ok(())
|
||||
}
|
||||
|
||||
fn config_did_change(&self) -> Future<()> {
|
||||
fn config_did_change(&self, _config: &WindowConfigHandle) -> Future<()> {
|
||||
Future::ok(())
|
||||
}
|
||||
}
|
||||
@ -249,5 +249,5 @@ pub trait WindowOpsMut {
|
||||
|
||||
fn toggle_fullscreen(&mut self) {}
|
||||
|
||||
fn config_did_change(&mut self) {}
|
||||
fn config_did_change(&mut self, _config: &WindowConfigHandle) {}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crate::connection::ConnectionOps;
|
||||
use crate::{
|
||||
config, Clipboard, Connection, Dimensions, KeyCode, KeyEvent, Modifiers, MouseButtons,
|
||||
MouseCursor, MouseEvent, MouseEventKind, MousePress, Point, Rect, ScreenPoint, Size,
|
||||
WindowCallbacks, WindowDecorations, WindowOps, WindowOpsMut,
|
||||
WindowCallbacks, WindowConfigHandle, WindowDecorations, WindowOps, WindowOpsMut,
|
||||
};
|
||||
use anyhow::{anyhow, bail, ensure};
|
||||
use cocoa::appkit::{
|
||||
@ -33,6 +33,7 @@ use std::cell::RefCell;
|
||||
use std::ffi::c_void;
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
fn round_away_from_zerof(value: f64) -> f64 {
|
||||
@ -317,6 +318,7 @@ pub(crate) struct WindowInner {
|
||||
window_id: usize,
|
||||
view: StrongPtr,
|
||||
window: StrongPtr,
|
||||
config: WindowConfigHandle,
|
||||
}
|
||||
|
||||
fn function_key_to_keycode(function_key: char) -> KeyCode {
|
||||
@ -356,9 +358,15 @@ impl Window {
|
||||
width: usize,
|
||||
height: usize,
|
||||
callbacks: Box<dyn WindowCallbacks>,
|
||||
config: Option<&WindowConfigHandle>,
|
||||
) -> anyhow::Result<Window> {
|
||||
let config = match config {
|
||||
Some(c) => Arc::clone(c),
|
||||
None => crate::config(),
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let style_mask = decoration_to_mask(config().decorations());
|
||||
let style_mask = decoration_to_mask(config.decorations());
|
||||
let rect = NSRect::new(
|
||||
NSPoint::new(0., 0.),
|
||||
NSSize::new(width as f64, height as f64),
|
||||
@ -381,6 +389,7 @@ impl Window {
|
||||
key_is_down: None,
|
||||
dead_pending: None,
|
||||
fullscreen: None,
|
||||
config: Arc::clone(&config),
|
||||
}));
|
||||
|
||||
let window: id = msg_send![get_window_class(), alloc];
|
||||
@ -442,13 +451,14 @@ impl Window {
|
||||
window_id,
|
||||
window,
|
||||
view,
|
||||
config: Arc::clone(&config),
|
||||
}));
|
||||
conn.windows
|
||||
.borrow_mut()
|
||||
.insert(window_id, Rc::clone(&window_inner));
|
||||
|
||||
let window = Window(window_id);
|
||||
window.config_did_change();
|
||||
window.config_did_change(&config);
|
||||
|
||||
inner.borrow_mut().enable_opengl()?;
|
||||
// Synthesize a resize event immediately; this allows
|
||||
@ -574,9 +584,10 @@ impl WindowOps for Window {
|
||||
})
|
||||
}
|
||||
|
||||
fn config_did_change(&self) -> Future<()> {
|
||||
fn config_did_change(&self, config: &WindowConfigHandle) -> Future<()> {
|
||||
let config = Arc::clone(config);
|
||||
Connection::with_window_inner(self.0, move |inner| {
|
||||
inner.config_did_change();
|
||||
inner.config_did_change(&config);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
@ -627,7 +638,7 @@ impl WindowInner {
|
||||
|
||||
fn apply_decorations(&mut self) {
|
||||
if !self.is_fullscreen() {
|
||||
let mask = decoration_to_mask(config().decorations());
|
||||
let mask = decoration_to_mask(self.config.decorations());
|
||||
unsafe {
|
||||
self.window.setStyleMask_(mask);
|
||||
/*
|
||||
@ -690,7 +701,7 @@ impl WindowInner {
|
||||
// Restore prior dimensions
|
||||
self.window.orderOut_(nil);
|
||||
self.window
|
||||
.setStyleMask_(decoration_to_mask(config().decorations()));
|
||||
.setStyleMask_(decoration_to_mask(self.config.decorations()));
|
||||
self.window.setFrame_display_(saved_rect, YES);
|
||||
self.window.makeKeyAndOrderFront_(nil);
|
||||
self.window.setOpaque_(NO);
|
||||
@ -726,7 +737,7 @@ impl WindowInner {
|
||||
}
|
||||
|
||||
fn update_window_shadow(&mut self) {
|
||||
let is_opaque = if config().window_background_opacity() >= 1.0 {
|
||||
let is_opaque = if self.config.window_background_opacity() >= 1.0 {
|
||||
YES
|
||||
} else {
|
||||
NO
|
||||
@ -826,7 +837,7 @@ impl WindowOpsMut for WindowInner {
|
||||
if let Some(window_view) = WindowView::get_this(unsafe { &**self.view }) {
|
||||
window_view.inner.borrow_mut().text_cursor_position = cursor;
|
||||
}
|
||||
if config().use_ime() {
|
||||
if self.config.use_ime() {
|
||||
unsafe {
|
||||
let input_context: id = msg_send![&**self.view, inputContext];
|
||||
let () = msg_send![input_context, invalidateCharacterCoordinates];
|
||||
@ -835,7 +846,7 @@ impl WindowOpsMut for WindowInner {
|
||||
}
|
||||
|
||||
fn toggle_fullscreen(&mut self) {
|
||||
let native_fullscreen = config().native_macos_fullscreen_mode();
|
||||
let native_fullscreen = self.config.native_macos_fullscreen_mode();
|
||||
|
||||
// If they changed their config since going full screen, be sure
|
||||
// to undo whichever fullscreen mode they had active rather than
|
||||
@ -852,7 +863,11 @@ impl WindowOpsMut for WindowInner {
|
||||
}
|
||||
}
|
||||
|
||||
fn config_did_change(&mut self) {
|
||||
fn config_did_change(&mut self, config: &WindowConfigHandle) {
|
||||
self.config = Arc::clone(config);
|
||||
if let Some(window_view) = WindowView::get_this(unsafe { &**self.view }) {
|
||||
window_view.inner.borrow_mut().config = Arc::clone(config);
|
||||
}
|
||||
self.update_window_shadow();
|
||||
self.apply_decorations();
|
||||
}
|
||||
@ -900,6 +915,8 @@ struct Inner {
|
||||
/// When using simple fullscreen mode, this tracks
|
||||
/// the window dimensions that need to be restored
|
||||
fullscreen: Option<NSRect>,
|
||||
|
||||
config: WindowConfigHandle,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -1000,7 +1017,7 @@ impl Inner {
|
||||
|
||||
let mods = key_modifiers(modifier_flags);
|
||||
|
||||
let config = config();
|
||||
let config = &self.config;
|
||||
|
||||
let use_dead_keys = if !config.use_dead_keys() {
|
||||
false
|
||||
|
@ -514,7 +514,7 @@ impl WindowOpsMut for WindowInner {
|
||||
imc.set_position(cursor.origin.x.max(0) as i32, cursor.origin.y.max(0) as i32);
|
||||
}
|
||||
|
||||
fn config_did_change(&mut self) {
|
||||
fn config_did_change(&mut self, _config: &WindowConfigHandle) {
|
||||
self.apply_decoration();
|
||||
}
|
||||
|
||||
@ -615,9 +615,10 @@ impl WindowOps for Window {
|
||||
})
|
||||
}
|
||||
|
||||
fn config_did_change(&self) -> Future<()> {
|
||||
fn config_did_change(&self, config: &WindowConfigHandle) -> Future<()> {
|
||||
let config = Arc::clone(config);
|
||||
Connection::with_window_inner(self.0, move |inner| {
|
||||
inner.config_did_change();
|
||||
inner.config_did_change(&config);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
@ -849,7 +849,7 @@ impl WindowOpsMut for XWindowInner {
|
||||
self.set_fullscreen_hint(!fullscreen).ok();
|
||||
}
|
||||
|
||||
fn config_did_change(&mut self) {
|
||||
fn config_did_change(&mut self, _config: &WindowConfigHandle) {
|
||||
let _ = self.adjust_decorations(config().decorations());
|
||||
}
|
||||
|
||||
@ -935,9 +935,10 @@ impl WindowOps for XWindow {
|
||||
})
|
||||
}
|
||||
|
||||
fn config_did_change(&self) -> Future<()> {
|
||||
fn config_did_change(&self, config: &WindowConfigHandle) -> Future<()> {
|
||||
let config = Arc::clone(config);
|
||||
XConnection::with_window_inner(self.0, |inner| {
|
||||
inner.config_did_change();
|
||||
inner.config_did_change(&config);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
@ -142,11 +142,11 @@ impl WindowOps for Window {
|
||||
}
|
||||
}
|
||||
|
||||
fn config_did_change(&self) -> Future<()> {
|
||||
fn config_did_change(&self, config: &WindowConfigHandle) -> Future<()> {
|
||||
match self {
|
||||
Self::X11(x) => x.config_did_change(),
|
||||
Self::X11(x) => x.config_did_change(config),
|
||||
#[cfg(feature = "wayland")]
|
||||
Self::Wayland(w) => w.config_did_change(),
|
||||
Self::Wayland(w) => w.config_did_change(config),
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user