1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-19 02:37:51 +03:00

macos: try to avoid the notch

Flesh out the get_os_parameters impl for macOS.  When running on a
system that provides `NSScreen::safeAreaInsets`, use that to determine
the border required to avoid the "notch" on certain models of mac.

In the GUI layer: when the os parameters include a border, adjust
the render position to account for it.

This is a bit of a speculative change, as I don't have a mac with
a notch.

refs: https://github.com/wez/wezterm/issues/1737
This commit is contained in:
Wez Furlong 2022-03-26 22:47:42 -07:00
parent a61d3a1b99
commit 4e343eb1e5
5 changed files with 103 additions and 21 deletions

View File

@ -15,6 +15,7 @@ As features stabilize some brief notes about them will accumulate here.
#### Changed
#### Updated and Improved
* Bundled harfbuzz to 4.1.0
* On macOS, non-native fullscreen mode now attempts to avoid the notch on systems that have one. [#1737](https://github.com/wez/wezterm/issues/1737)
#### Fixed
* Incorrect csi-u encoding with non-ascii characters. [#1746](https://github.com/wez/wezterm/issues/1746)

View File

@ -61,11 +61,13 @@ impl super::TermWindow {
self.current_mouse_event.replace(event.clone());
let border = self.get_os_border();
let first_line_offset = if self.show_tab_bar && !self.config.tab_bar_at_bottom {
self.tab_bar_pixel_height().unwrap_or(0.) as isize
} else {
0
};
} + border.top.get();
let (padding_left, padding_top) = self.padding_left_top();

View File

@ -777,6 +777,8 @@ impl super::TermWindow {
.min_width(Some(Dimension::Pixels(self.dimensions.pixel_width as f32)))
.colors(bar_colors);
let border = self.get_os_border();
let mut computed = self.compute_element(
&LayoutContext {
height: DimensionContext {
@ -790,10 +792,10 @@ impl super::TermWindow {
pixel_cell: metrics.cell_size.width as f32,
},
bounds: euclid::rect(
border.left.get() as f32,
0.,
0.,
self.dimensions.pixel_width as f32,
self.dimensions.pixel_height as f32,
self.dimensions.pixel_width as f32 - (border.left + border.right).get() as f32,
self.dimensions.pixel_height as f32 - (border.top + border.bottom).get() as f32,
),
metrics: &metrics,
gl_state: self.render_state.as_ref().unwrap(),
@ -801,12 +803,15 @@ impl super::TermWindow {
&tabs,
)?;
if self.config.tab_bar_at_bottom {
computed.translate(euclid::vec2(
0.,
self.dimensions.pixel_height as f32 - computed.bounds.height(),
));
}
computed.translate(euclid::vec2(
0.,
if self.config.tab_bar_at_bottom {
self.dimensions.pixel_height as f32
- (computed.bounds.height() + border.bottom.get() as f32)
} else {
border.top.get() as f32
},
));
Ok(computed)
}
@ -827,6 +832,13 @@ impl super::TermWindow {
Ok(ui_items)
}
pub fn get_os_border(&self) -> window::parameters::Border {
self.os_parameters
.as_ref()
.and_then(|p| p.border_dimensions.clone())
.unwrap_or_default()
}
fn paint_tab_bar(&mut self) -> anyhow::Result<()> {
if self.config.use_fancy_tab_bar {
if self.fancy_tab_bar.is_none() {
@ -839,12 +851,15 @@ impl super::TermWindow {
return Ok(());
}
let border = self.get_os_border();
let palette = self.palette().clone();
let tab_bar_height = self.tab_bar_pixel_height()?;
let tab_bar_y = if self.config.tab_bar_at_bottom {
((self.dimensions.pixel_height as f32) - tab_bar_height).max(0.)
((self.dimensions.pixel_height as f32) - (tab_bar_height + border.bottom.get() as f32))
.max(0.)
} else {
0.
border.top.get() as f32
};
// Register the tab bar location
@ -1007,7 +1022,9 @@ impl super::TermWindow {
} else {
0.
};
let top_pixel_y = tab_bar_height + padding_top;
let border = self.get_os_border();
let top_pixel_y = tab_bar_height + padding_top + border.top.get() as f32;
let cursor = pos.pane.get_cursor_position();
if pos.is_active {
@ -1521,7 +1538,7 @@ impl super::TermWindow {
self.tab_bar_pixel_height()?
} else {
0.
};
} + self.get_os_border().top.get() as f32;
let (padding_left, padding_top) = self.padding_left_top();

View File

@ -3,18 +3,20 @@
use super::{nsstring, nsstring_to_str};
use crate::connection::ConnectionOps;
use crate::parameters::{Border, Parameters, TitleBar};
use crate::{
Clipboard, Connection, DeadKeyStatus, Dimensions, Handled, KeyCode, KeyEvent, Modifiers,
MouseButtons, MouseCursor, MouseEvent, MouseEventKind, MousePress, Point, RawKeyEvent, Rect,
ScreenPoint, Size, WindowDecorations, WindowEvent, WindowEventSender, WindowOps, WindowState,
Clipboard, Connection, DeadKeyStatus, Dimensions, Handled, KeyCode, KeyEvent, Length,
Modifiers, MouseButtons, MouseCursor, MouseEvent, MouseEventKind, MousePress, Point,
RawKeyEvent, Rect, ScreenPoint, Size, WindowDecorations, WindowEvent, WindowEventSender,
WindowOps, WindowState,
};
use anyhow::{anyhow, bail, ensure};
use async_trait::async_trait;
use cocoa::appkit::{
self, NSApplication, NSApplicationActivateIgnoringOtherApps, NSApplicationPresentationOptions,
NSBackingStoreBuffered, NSEvent, NSEventModifierFlags, NSOpenGLContext, NSOpenGLPixelFormat,
NSRunningApplication, NSScreen, NSView, NSViewHeightSizable, NSViewWidthSizable, NSWindow,
NSWindowStyleMask,
self, CGFloat, NSApplication, NSApplicationActivateIgnoringOtherApps,
NSApplicationPresentationOptions, NSBackingStoreBuffered, NSEvent, NSEventModifierFlags,
NSOpenGLContext, NSOpenGLPixelFormat, NSRunningApplication, NSScreen, NSView,
NSViewHeightSizable, NSViewWidthSizable, NSWindow, NSWindowStyleMask,
};
use cocoa::base::*;
use cocoa::foundation::{
@ -675,6 +677,65 @@ impl WindowOps for Window {
Ok(())
});
}
fn get_os_parameters(
&self,
_config: &ConfigHandle,
window_state: WindowState,
) -> anyhow::Result<Option<Parameters>> {
let raw = self.raw_window_handle();
// We implement this method primarily to provide Notch-avoidance for
// systems with a notch.
// We only need this for non-native full screen mode.
let native_full_screen = match raw {
RawWindowHandle::MacOS(raw) => {
let style_mask = unsafe { NSWindow::styleMask(raw.ns_window as *mut Object) };
style_mask.contains(NSWindowStyleMask::NSFullScreenWindowMask)
}
_ => false,
};
let border_dimensions =
if window_state.contains(WindowState::FULL_SCREEN) && !native_full_screen {
let main_screen = unsafe { NSScreen::mainScreen(nil) };
let has_safe_area_insets: BOOL =
unsafe { msg_send![main_screen, respondsToSelector: sel!(safeAreaInsets)] };
if has_safe_area_insets {
#[derive(Debug)]
struct NSEdgeInsets {
top: CGFloat,
left: CGFloat,
bottom: CGFloat,
right: CGFloat,
}
let insets: NSEdgeInsets = unsafe { msg_send![main_screen, safeAreaInsets] };
log::trace!("{:?}", insets);
Some(Border {
top: Length::new(insets.top.ceil() as isize),
left: Length::new(insets.left.ceil() as isize),
right: Length::new(insets.right.ceil() as isize),
bottom: Length::new(insets.bottom.ceil() as isize),
color: crate::color::LinearRgba::with_components(0., 0., 0., 1.),
})
} else {
None
}
} else {
None
};
Ok(Some(Parameters {
title_bar: TitleBar {
padding_left: Length::new(0),
padding_right: Length::new(0),
height: None,
font_and_size: None,
},
border_dimensions,
}))
}
}
/// Convert from a macOS screen coordinate with the origin in the bottom left

View File

@ -12,6 +12,7 @@ pub struct TitleBar {
pub font_and_size: Option<FontAndSize>,
}
#[derive(Default, Clone)]
pub struct Border {
pub top: Length,
pub left: Length,