Buttonless option for macOS (#1076)

* Buttonless option for macOS

* Properly export PATH on macOS when ran from Finder #1072

* Merge conflicts resolved

* Refactoring frame options

* Adding frame file; forgot to add

* Updating window files

* Updated from revisions; .vscode folder added to .gitignore

* Formatting

* Remove comment of shadow option in frame decoration.

* Fix transparency for buttonless

* General fix for buttonless and transparency

* Formatting

* revert unecessary changes

Co-authored-by: Keith Simmons <keith@the-simmons.net>
Co-authored-by: Keith Simmons <keithsim@microsoft.com>
macos-click-through
Louis C. Murguia 3 years ago committed by GitHub
parent 9cfac28ac8
commit 3efc3c1759
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,4 +1,4 @@
use crate::{dimensions::Dimensions, settings::*}; use crate::{dimensions::Dimensions, frame::Frame, settings::*};
use clap::{App, Arg}; use clap::{App, Arg};
@ -13,7 +13,7 @@ pub struct CmdLineSettings {
pub remote_tcp: Option<String>, pub remote_tcp: Option<String>,
pub wsl: bool, pub wsl: bool,
// Command-line flags with environment variable fallback // Command-line flags with environment variable fallback
pub frameless: bool, pub frame: Frame,
pub maximized: bool, pub maximized: bool,
pub multi_grid: bool, pub multi_grid: bool,
pub no_idle: bool, pub no_idle: bool,
@ -36,7 +36,7 @@ impl Default for CmdLineSettings {
remote_tcp: None, remote_tcp: None,
wsl: false, wsl: false,
// Command-line flags with environment variable fallback // Command-line flags with environment variable fallback
frameless: false, frame: Frame::Full,
maximized: false, maximized: false,
multi_grid: false, multi_grid: false,
no_idle: false, no_idle: false,
@ -98,9 +98,10 @@ pub fn handle_command_line_arguments(args: Vec<String>) -> Result<(), String> {
) )
// Command-line flags with environment variable fallback // Command-line flags with environment variable fallback
.arg( .arg(
Arg::with_name("frameless") Arg::with_name("frame")
.long("frameless") .long("frame")
.help("Removes the window frame. NOTE: Window might not be resizable after this setting is enabled.") .takes_value(true)
.help("Configure the window frame. NOTE: Window might not be resizable if setting is None.")
) )
.arg( .arg(
Arg::with_name("maximized") Arg::with_name("maximized")
@ -169,7 +170,13 @@ pub fn handle_command_line_arguments(args: Vec<String>) -> Result<(), String> {
remote_tcp: matches.value_of("remote_tcp").map(|i| i.to_owned()), remote_tcp: matches.value_of("remote_tcp").map(|i| i.to_owned()),
wsl: matches.is_present("wsl"), wsl: matches.is_present("wsl"),
// Command-line flags with environment variable fallback // Command-line flags with environment variable fallback
frameless: matches.is_present("frameless") || std::env::var("NEOVIDE_FRAMELESS").is_ok(), frame: match matches.value_of("frame") {
Some(val) => Frame::from_string(val.to_string()),
None => match std::env::var("NEOVIDE_FRAME") {
Ok(f) => Frame::from_string(f),
Err(_) => Frame::Full,
},
},
maximized: matches.is_present("maximized") || std::env::var("NEOVIDE_MAXIMIZED").is_ok(), maximized: matches.is_present("maximized") || std::env::var("NEOVIDE_MAXIMIZED").is_ok(),
multi_grid: matches.is_present("multi_grid") || std::env::var("NEOVIDE_MULTIGRID").is_ok(), multi_grid: matches.is_present("multi_grid") || std::env::var("NEOVIDE_MULTIGRID").is_ok(),
no_idle: matches.is_present("noidle") || std::env::var("NEOVIDE_NO_IDLE").is_ok(), no_idle: matches.is_present("noidle") || std::env::var("NEOVIDE_NO_IDLE").is_ok(),
@ -308,14 +315,14 @@ mod tests {
#[test] #[test]
fn test_frameless_flag() { fn test_frameless_flag() {
let args: Vec<String> = vec!["neovide", "--frameless"] let args: Vec<String> = vec!["neovide", "--frame=full"]
.iter() .iter()
.map(|s| s.to_string()) .map(|s| s.to_string())
.collect(); .collect();
let _accessing_settings = ACCESSING_SETTINGS.lock().unwrap(); let _accessing_settings = ACCESSING_SETTINGS.lock().unwrap();
handle_command_line_arguments(args).expect("Could not parse arguments"); handle_command_line_arguments(args).expect("Could not parse arguments");
assert_eq!(SETTINGS.get::<CmdLineSettings>().frameless, true); assert_eq!(SETTINGS.get::<CmdLineSettings>().frame, Frame::Full);
} }
#[test] #[test]
@ -323,9 +330,9 @@ mod tests {
let args: Vec<String> = vec!["neovide"].iter().map(|s| s.to_string()).collect(); let args: Vec<String> = vec!["neovide"].iter().map(|s| s.to_string()).collect();
let _accessing_settings = ACCESSING_SETTINGS.lock().unwrap(); let _accessing_settings = ACCESSING_SETTINGS.lock().unwrap();
set_var("NEOVIDE_FRAMELESS", "true"); set_var("NEOVIDE_FRAME", "none");
handle_command_line_arguments(args).expect("Could not parse arguments"); handle_command_line_arguments(args).expect("Could not parse arguments");
assert_eq!(SETTINGS.get::<CmdLineSettings>().frameless, true); assert_eq!(SETTINGS.get::<CmdLineSettings>().frame, Frame::None);
} }
#[test] #[test]

@ -0,0 +1,30 @@
// Options for the frame decorations
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Frame {
Full,
#[cfg(target_os = "macos")]
Transparent,
#[cfg(target_os = "macos")]
Buttonless,
None,
}
impl Default for Frame {
fn default() -> Frame {
Frame::Full
}
}
impl Frame {
pub fn from_string(decoration: String) -> Frame {
match decoration.to_lowercase().as_str() {
"full" => Frame::Full,
#[cfg(target_os = "macos")]
"transparent" => Frame::Transparent,
#[cfg(target_os = "macos")]
"buttonless" => Frame::Buttonless,
"none" => Frame::None,
_ => Frame::Full,
}
}
}

@ -16,6 +16,7 @@ mod dimensions;
mod editor; mod editor;
mod error_handling; mod error_handling;
mod event_aggregator; mod event_aggregator;
mod frame;
mod redraw_scheduler; mod redraw_scheduler;
mod renderer; mod renderer;
mod running_tracker; mod running_tracker;

@ -16,6 +16,9 @@ use glutin::{
use log::trace; use log::trace;
use tokio::sync::mpsc::UnboundedReceiver; use tokio::sync::mpsc::UnboundedReceiver;
#[cfg(target_os = "macos")]
use glutin::platform::macos::WindowBuilderExtMacOS;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
use glutin::platform::unix::WindowBuilderExtUnix; use glutin::platform::unix::WindowBuilderExtUnix;
@ -30,6 +33,7 @@ use crate::{
dimensions::Dimensions, dimensions::Dimensions,
editor::EditorCommand, editor::EditorCommand,
event_aggregator::EVENT_AGGREGATOR, event_aggregator::EVENT_AGGREGATOR,
frame::Frame,
redraw_scheduler::REDRAW_SCHEDULER, redraw_scheduler::REDRAW_SCHEDULER,
renderer::Renderer, renderer::Renderer,
running_tracker::*, running_tracker::*,
@ -275,12 +279,34 @@ pub fn create_window() {
} }
} }
let mut winit_window_builder = window::WindowBuilder::new() let winit_window_builder = window::WindowBuilder::new()
.with_title("Neovide") .with_title("Neovide")
.with_window_icon(Some(icon)) .with_window_icon(Some(icon))
.with_maximized(maximized) .with_maximized(maximized)
.with_transparent(true);
let frame_decoration = cmd_line_settings.frame;
// There is only two options for windows & linux, no need to match more options.
#[cfg(not(target_os = "macos"))]
let mut winit_window_builder =
winit_window_builder.with_decorations(frame_decoration == Frame::Full);
#[cfg(target_os = "macos")]
let mut winit_window_builder = match frame_decoration {
Frame::Full => winit_window_builder,
Frame::None => winit_window_builder.with_decorations(false),
Frame::Buttonless => winit_window_builder
.with_transparent(true) .with_transparent(true)
.with_decorations(!cmd_line_settings.frameless); .with_title_hidden(true)
.with_titlebar_buttons_hidden(true)
.with_titlebar_transparent(true)
.with_fullsize_content_view(true),
Frame::Transparent => winit_window_builder
.with_title_hidden(true)
.with_titlebar_transparent(true)
.with_fullsize_content_view(true),
};
if let Some(previous_position) = previous_position { if let Some(previous_position) = previous_position {
if !maximized { if !maximized {

Loading…
Cancel
Save