Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inset Mac OS traffic lights #513

Merged
merged 29 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
96f6504
new example
haasal Aug 3, 2022
e05e520
feat(macos): Fixed the traffic light example
haasal Aug 3, 2022
7c2f1a7
feat(macos): Implemented and exposed a traffic light reposition metho…
haasal Aug 3, 2022
47a52a3
fix(macos): fixed the issue with the artifact on resize
haasal Aug 6, 2022
2e30025
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
05e6d10
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
a8e3b7a
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
c7e1f85
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
d974776
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
05f7933
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
a73ddd5
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
05d2512
Update src/platform_impl/macos/window.rs
haasal Apr 6, 2023
8a0be7a
Delete macos_traffic_lights.rs
haasal Apr 28, 2023
7016d9b
Update window.rs
haasal Apr 28, 2023
70e8d87
refactor: Replaced type of inset with LogicalSize + docs
haasal Apr 28, 2023
e63fd8c
fixes
JonasKruckenberg May 3, 2023
a62fcf9
revert accidental commit
JonasKruckenberg May 3, 2023
5128b26
add back example
JonasKruckenberg May 3, 2023
46dfb40
fix(macos): traffic light offset now works as expected
haasal Oct 19, 2023
39cd6ff
refactor(macos): removed the traffic light example
haasal Oct 19, 2023
281abe7
feat(macos): added set_traffic_light_position back in
haasal Oct 19, 2023
6d780b0
delete comment
haasal Oct 25, 2023
3743a5e
revert(macos): reverted accidental deletion of null check
haasal Oct 25, 2023
2255f97
refactor(macos): changed traffic light inset to LogicalPosition<f64>
haasal Oct 25, 2023
8640e3b
refactor(macos): changed pulic api back to Position
haasal Oct 25, 2023
6bdbc78
cleanup after rebase
amrbashir Oct 26, 2023
c7f8a94
more cleanup
amrbashir Oct 26, 2023
fddda47
Merge branch 'dev' into inset
amrbashir Oct 26, 2023
e352f23
fix macos
amrbashir Oct 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/platform/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use std::os::raw::c_void;

use crate::{
dpi::LogicalSize,
dpi::{LogicalSize, Position},
event_loop::{EventLoop, EventLoopWindowTarget},
monitor::MonitorHandle,
platform_impl::{get_aux_state_mut, Parent},
Expand Down Expand Up @@ -49,6 +49,8 @@ pub trait WindowExtMacOS {
/// Sets whether or not the window has shadow.
fn set_has_shadow(&self, has_shadow: bool);

/// Set the window traffic light position relative to the upper left corner
fn set_traffic_light_inset<P: Into<Position>>(&self, position: P);
/// Put the window in a state which indicates a file save is required.
///
/// <https://developer.apple.com/documentation/appkit/nswindow/1419311-isdocumentedited>
Expand Down Expand Up @@ -105,6 +107,11 @@ impl WindowExtMacOS for Window {
self.window.set_has_shadow(has_shadow)
}

#[inline]
fn set_traffic_light_inset<P: Into<Position>>(&self, position: P) {
self.window.set_traffic_light_inset(position)
}

#[inline]
fn set_is_document_edited(&self, edited: bool) {
self.window.set_is_document_edited(edited)
Expand Down Expand Up @@ -194,6 +201,8 @@ pub trait WindowBuilderExtMacOS {
fn with_disallow_hidpi(self, disallow_hidpi: bool) -> WindowBuilder;
/// Sets whether or not the window has shadow.
fn with_has_shadow(self, has_shadow: bool) -> WindowBuilder;
/// Sets the traffic light position to (x, y) relative to the upper left corner
fn with_traffic_light_inset<P: Into<Position>>(self, inset: P) -> WindowBuilder;
/// Sets whether the system can automatically organize windows into tabs.
fn with_automatic_window_tabbing(self, automatic_tabbing: bool) -> WindowBuilder;
/// Defines the window [tabbing identifier].
Expand Down Expand Up @@ -266,6 +275,12 @@ impl WindowBuilderExtMacOS for WindowBuilder {
self
}

#[inline]
fn with_traffic_light_inset<P: Into<Position>>(mut self, inset: P) -> WindowBuilder {
self.platform_specific.traffic_light_inset = Some(inset.into());
self
}

#[inline]
fn with_automatic_window_tabbing(mut self, automatic_tabbing: bool) -> WindowBuilder {
self.platform_specific.automatic_tabbing = automatic_tabbing;
Expand Down
35 changes: 34 additions & 1 deletion src/platform_impl/macos/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{
};

use cocoa::{
appkit::{NSApp, NSEvent, NSEventModifierFlags, NSEventPhase, NSView, NSWindow},
appkit::{NSApp, NSEvent, NSEventModifierFlags, NSEventPhase, NSView, NSWindow, NSWindowButton},
base::{id, nil},
foundation::{NSInteger, NSPoint, NSRect, NSSize, NSString, NSUInteger},
};
Expand Down Expand Up @@ -70,6 +70,7 @@ pub(super) struct ViewState {
pub(super) modifiers: ModifiersState,
phys_modifiers: HashSet<KeyCode>,
tracking_rect: Option<NSInteger>,
pub(super) traffic_light_inset: Option<LogicalPosition<f64>>,
}

impl ViewState {
Expand All @@ -91,6 +92,7 @@ pub fn new_view(ns_window: id) -> (IdRef, Weak<Mutex<CursorState>>) {
modifiers: Default::default(),
phys_modifiers: Default::default(),
tracking_rect: None,
traffic_light_inset: None,
};
unsafe {
// This is free'd in `dealloc`
Expand Down Expand Up @@ -384,6 +386,11 @@ extern "C" fn draw_rect(this: &Object, _sel: Sel, rect: NSRect) {
let state_ptr: *mut c_void = *this.get_ivar("taoState");
let state = &mut *(state_ptr as *mut ViewState);

if let Some(position) = state.traffic_light_inset {
let window = state.ns_window;
inset_traffic_lights(window, position);
}

AppState::handle_redraw(WindowId(get_window_id(state.ns_window)));

let superclass = util::superclass(this);
Expand Down Expand Up @@ -1176,3 +1183,29 @@ extern "C" fn wants_key_down_for_event(_this: &Object, _sel: Sel, _event: id) ->
extern "C" fn accepts_first_mouse(_this: &Object, _sel: Sel, _event: id) -> BOOL {
YES
}

pub unsafe fn inset_traffic_lights<W: NSWindow + Copy>(window: W, position: LogicalPosition<f64>) {
let (x, y) = (position.x, position.y);

let close = window.standardWindowButton_(NSWindowButton::NSWindowCloseButton);
let miniaturize = window.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton);
let zoom = window.standardWindowButton_(NSWindowButton::NSWindowZoomButton);

let title_bar_container_view = close.superview().superview();

let close_rect = NSView::frame(close);
let title_bar_frame_height = close_rect.size.height + y;
let mut title_bar_rect = NSView::frame(title_bar_container_view);
title_bar_rect.size.height = title_bar_frame_height;
title_bar_rect.origin.y = window.frame().size.height - title_bar_frame_height;
let _: () = msg_send![title_bar_container_view, setFrame: title_bar_rect];

let window_buttons = vec![close, miniaturize, zoom];
let space_between = NSView::frame(miniaturize).origin.x - close_rect.origin.x;

for (i, button) in window_buttons.into_iter().enumerate() {
let mut rect = NSView::frame(button);
rect.origin.x = x + (i as f64 * space_between);
button.setFrameOrigin(rect.origin);
}
}
22 changes: 21 additions & 1 deletion src/platform_impl/macos/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use objc::{
runtime::{Class, Object, Sel, BOOL, NO, YES},
};

use super::util::ns_string_to_rust;
use super::{util::ns_string_to_rust, view::ViewState};

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id(pub usize);
Expand Down Expand Up @@ -91,6 +91,7 @@ pub struct PlatformSpecificWindowBuilderAttributes {
pub resize_increments: Option<LogicalSize<f64>>,
pub disallow_hidpi: bool,
pub has_shadow: bool,
pub traffic_light_inset: Option<Position>,
pub automatic_tabbing: bool,
pub tabbing_identifier: Option<String>,
}
Expand All @@ -109,6 +110,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
resize_increments: None,
disallow_hidpi: false,
has_shadow: true,
traffic_light_inset: None,
automatic_tabbing: true,
tabbing_identifier: None,
}
Expand All @@ -125,6 +127,14 @@ unsafe fn create_view(
ns_view.setWantsBestResolutionOpenGLSurface_(YES);
}

if let Some(position) = pl_attribs.traffic_light_inset {
let state_ptr: *mut c_void = *(**ns_view).get_ivar("taoState");
let state = &mut *(state_ptr as *mut ViewState);
let scale_factor = NSWindow::backingScaleFactor(ns_window);
let position = position.to_logical(scale_factor);
state.traffic_light_inset = Some(position);
}

// On Mojave, views automatically become layer-backed shortly after being added to
// a window. Changing the layer-backedness of a view breaks the association between
// the view and its associated OpenGL context. To work around this, on Mojave we
Expand Down Expand Up @@ -1547,6 +1557,16 @@ impl WindowExtMacOS for UnownedWindow {
}
}

#[inline]
fn set_traffic_light_inset<P: Into<Position>>(&self, position: P) {
let position: Position = position.into();
unsafe {
let state_ptr: *mut c_void = *(**self.ns_view).get_ivar("taoState");
let state = &mut *(state_ptr as *mut ViewState);
state.traffic_light_inset = Some(position.to_logical(self.scale_factor()));
}
}

#[inline]
fn set_is_document_edited(&self, edited: bool) {
unsafe {
Expand Down
Loading