mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-25 14:05:41 -05:00
Update to glutin 0.17
Changes: • Use the with_hardware_acceleration function on the ContextBuilder to not require the discrete GPU • Remove the LMenu and RMenu virtual key codes (winit 0.16.0 removed these because Windows now generates LAlt and RAlt instead • Replace set_cursor_state with hide_cursor (winit 0.16.0 removed the set_cursor_state function) * Replace GlWindow::hidpi_factor with GlWindow::get_hidpi_factor and change to expecting an f64 * Use the glutin/winit dpi size and position types where possible Notes: The Resized event emitted by glutin carrys a logical/pixel size but I suspect that previously it was a physical/point size Resizing the terminal, window and renderer all need physical/point sizes so a conversion needs to be made when handling resized events
This commit is contained in:
parent
1adb5cb7fc
commit
3d8d336fd4
8 changed files with 79 additions and 167 deletions
|
@ -35,7 +35,7 @@ clap = "2"
|
||||||
fnv = "1"
|
fnv = "1"
|
||||||
unicode-width = "0.1"
|
unicode-width = "0.1"
|
||||||
arraydeque = "0.4"
|
arraydeque = "0.4"
|
||||||
glutin = "0.16"
|
glutin = "0.17"
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
base64 = "0.9.0"
|
base64 = "0.9.0"
|
||||||
static_assertions = "0.2.5"
|
static_assertions = "0.2.5"
|
||||||
|
|
|
@ -1903,7 +1903,6 @@ enum Key {
|
||||||
LAlt,
|
LAlt,
|
||||||
LBracket,
|
LBracket,
|
||||||
LControl,
|
LControl,
|
||||||
LMenu,
|
|
||||||
LShift,
|
LShift,
|
||||||
LWin,
|
LWin,
|
||||||
Mail,
|
Mail,
|
||||||
|
@ -1928,7 +1927,6 @@ enum Key {
|
||||||
RAlt,
|
RAlt,
|
||||||
RBracket,
|
RBracket,
|
||||||
RControl,
|
RControl,
|
||||||
RMenu,
|
|
||||||
RShift,
|
RShift,
|
||||||
RWin,
|
RWin,
|
||||||
Semicolon,
|
Semicolon,
|
||||||
|
@ -2064,7 +2062,6 @@ impl Key {
|
||||||
Key::LAlt => LAlt,
|
Key::LAlt => LAlt,
|
||||||
Key::LBracket => LBracket,
|
Key::LBracket => LBracket,
|
||||||
Key::LControl => LControl,
|
Key::LControl => LControl,
|
||||||
Key::LMenu => LMenu,
|
|
||||||
Key::LShift => LShift,
|
Key::LShift => LShift,
|
||||||
Key::LWin => LWin,
|
Key::LWin => LWin,
|
||||||
Key::Mail => Mail,
|
Key::Mail => Mail,
|
||||||
|
@ -2089,7 +2086,6 @@ impl Key {
|
||||||
Key::RAlt => RAlt,
|
Key::RAlt => RAlt,
|
||||||
Key::RBracket => RBracket,
|
Key::RBracket => RBracket,
|
||||||
Key::RControl => RControl,
|
Key::RControl => RControl,
|
||||||
Key::RMenu => RMenu,
|
|
||||||
Key::RShift => RShift,
|
Key::RShift => RShift,
|
||||||
Key::RWin => RWin,
|
Key::RWin => RWin,
|
||||||
Key::Semicolon => Semicolon,
|
Key::Semicolon => Semicolon,
|
||||||
|
|
|
@ -18,7 +18,7 @@ use std::sync::mpsc;
|
||||||
|
|
||||||
use parking_lot::{MutexGuard};
|
use parking_lot::{MutexGuard};
|
||||||
|
|
||||||
use Rgb;
|
use {LogicalPosition, LogicalSize, PhysicalSize, Rgb};
|
||||||
use cli;
|
use cli;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use font::{self, Rasterize};
|
use font::{self, Rasterize};
|
||||||
|
@ -27,7 +27,8 @@ use renderer::{self, GlyphCache, QuadRenderer};
|
||||||
use selection::Selection;
|
use selection::Selection;
|
||||||
use term::{Term, SizeInfo};
|
use term::{Term, SizeInfo};
|
||||||
|
|
||||||
use window::{self, Size, Pixels, Window, SetInnerSize};
|
use window::{self, Window};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
@ -93,8 +94,8 @@ pub struct Display {
|
||||||
renderer: QuadRenderer,
|
renderer: QuadRenderer,
|
||||||
glyph_cache: GlyphCache,
|
glyph_cache: GlyphCache,
|
||||||
render_timer: bool,
|
render_timer: bool,
|
||||||
rx: mpsc::Receiver<(u32, u32)>,
|
rx: mpsc::Receiver<LogicalSize>,
|
||||||
tx: mpsc::Sender<(u32, u32)>,
|
tx: mpsc::Sender<LogicalSize>,
|
||||||
meter: Meter,
|
meter: Meter,
|
||||||
font_size: font::Size,
|
font_size: font::Size,
|
||||||
size_info: SizeInfo,
|
size_info: SizeInfo,
|
||||||
|
@ -151,10 +152,10 @@ impl Display {
|
||||||
info!("device_pixel_ratio: {}", dpr);
|
info!("device_pixel_ratio: {}", dpr);
|
||||||
|
|
||||||
// Create renderer
|
// Create renderer
|
||||||
let mut renderer = QuadRenderer::new(config, viewport_size)?;
|
let mut renderer = QuadRenderer::new(config, viewport_size.to_physical(window.hidpi_factor()))?;
|
||||||
|
|
||||||
let (glyph_cache, cell_width, cell_height) =
|
let (glyph_cache, cell_width, cell_height) =
|
||||||
Self::new_glyph_cache(dpr, &mut renderer, config)?;
|
Self::new_glyph_cache(dpr as f32, &mut renderer, config)?;
|
||||||
|
|
||||||
|
|
||||||
let dimensions = options.dimensions()
|
let dimensions = options.dimensions()
|
||||||
|
@ -165,21 +166,21 @@ impl Display {
|
||||||
let width = cell_width as u32 * dimensions.columns_u32();
|
let width = cell_width as u32 * dimensions.columns_u32();
|
||||||
let height = cell_height as u32 * dimensions.lines_u32();
|
let height = cell_height as u32 * dimensions.lines_u32();
|
||||||
|
|
||||||
let new_viewport_size = Size {
|
let new_viewport_size = LogicalSize::new(
|
||||||
width: Pixels(width + 2 * u32::from(config.padding().x)),
|
(width + 2 * u32::from(config.padding().x)) as f64,
|
||||||
height: Pixels(height + 2 * u32::from(config.padding().y)),
|
(height + 2 * u32::from(config.padding().y)) as f64);
|
||||||
};
|
|
||||||
|
|
||||||
window.set_inner_size(&new_viewport_size);
|
window.set_inner_size(new_viewport_size);
|
||||||
renderer.resize(new_viewport_size.width.0 as _, new_viewport_size.height.0 as _);
|
renderer.resize(new_viewport_size.to_physical(dpr));
|
||||||
viewport_size = new_viewport_size
|
viewport_size = new_viewport_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Cell Size: ({} x {})", cell_width, cell_height);
|
info!("Cell Size: ({} x {})", cell_width, cell_height);
|
||||||
|
|
||||||
|
let psize = viewport_size.to_physical(window.hidpi_factor());
|
||||||
let size_info = SizeInfo {
|
let size_info = SizeInfo {
|
||||||
width: viewport_size.width.0 as f32,
|
width: psize.width as f32,
|
||||||
height: viewport_size.height.0 as f32,
|
height: psize.height as f32,
|
||||||
cell_width: cell_width as f32,
|
cell_width: cell_width as f32,
|
||||||
cell_height: cell_height as f32,
|
cell_height: cell_height as f32,
|
||||||
padding_x: f32::from(config.padding().x),
|
padding_x: f32::from(config.padding().x),
|
||||||
|
@ -265,7 +266,7 @@ impl Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn resize_channel(&self) -> mpsc::Sender<(u32, u32)> {
|
pub fn resize_channel(&self) -> mpsc::Sender<LogicalSize> {
|
||||||
self.tx.clone()
|
self.tx.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +288,10 @@ impl Display {
|
||||||
|
|
||||||
// Take most recent resize event, if any
|
// Take most recent resize event, if any
|
||||||
while let Ok(sz) = self.rx.try_recv() {
|
while let Ok(sz) = self.rx.try_recv() {
|
||||||
new_size = Some(sz);
|
// Resize events are emitted via glutin/winit with logical sizes
|
||||||
|
// However the terminal, window and renderer use physical sizes
|
||||||
|
// so a conversion must be done here
|
||||||
|
new_size = Some(sz.to_physical(self.window.hidpi_factor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Font size modification detected
|
// Font size modification detected
|
||||||
|
@ -297,16 +301,16 @@ impl Display {
|
||||||
|
|
||||||
if new_size == None {
|
if new_size == None {
|
||||||
// Force a resize to refresh things
|
// Force a resize to refresh things
|
||||||
new_size = Some((self.size_info.width as u32,
|
new_size = Some(PhysicalSize::new(self.size_info.width as f64,
|
||||||
self.size_info.height as u32));
|
self.size_info.height as f64));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive any resize events; only call gl::Viewport on last
|
// Receive any resize events; only call gl::Viewport on last
|
||||||
// available
|
// available
|
||||||
if let Some((w, h)) = new_size.take() {
|
if let Some(psize) = new_size.take() {
|
||||||
self.size_info.width = w as f32;
|
self.size_info.width = psize.width as f32;
|
||||||
self.size_info.height = h as f32;
|
self.size_info.height = psize.height as f32;
|
||||||
|
|
||||||
let size = &self.size_info;
|
let size = &self.size_info;
|
||||||
terminal.resize(size);
|
terminal.resize(size);
|
||||||
|
@ -315,8 +319,8 @@ impl Display {
|
||||||
item.on_resize(size)
|
item.on_resize(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.window.resize(w, h);
|
self.window.resize(psize);
|
||||||
self.renderer.resize(w as i32, h as i32);
|
self.renderer.resize(psize);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -425,6 +429,6 @@ impl Display {
|
||||||
padding_y: py, ..} = *terminal.size_info();
|
padding_y: py, ..} = *terminal.size_info();
|
||||||
let nspot_y = (py + (row + 1) as f32 * ch) as i32;
|
let nspot_y = (py + (row + 1) as f32 * ch) as i32;
|
||||||
let nspot_x = (px + col as f32 * cw) as i32;
|
let nspot_x = (px + col as f32 * cw) as i32;
|
||||||
self.window().set_ime_spot(nspot_x, nspot_y);
|
self.window().set_ime_spot(LogicalPosition::from((nspot_x, nspot_y)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
src/event.rs
20
src/event.rs
|
@ -21,6 +21,7 @@ use term::{Term, SizeInfo, TermMode};
|
||||||
use util::limit;
|
use util::limit;
|
||||||
use util::fmt::Red;
|
use util::fmt::Red;
|
||||||
use window::Window;
|
use window::Window;
|
||||||
|
use LogicalSize;
|
||||||
|
|
||||||
/// Byte sequences are sent to a `Notify` in response to some events
|
/// Byte sequences are sent to a `Notify` in response to some events
|
||||||
pub trait Notify {
|
pub trait Notify {
|
||||||
|
@ -217,7 +218,7 @@ pub struct Processor<N> {
|
||||||
wait_for_event: bool,
|
wait_for_event: bool,
|
||||||
notifier: N,
|
notifier: N,
|
||||||
mouse: Mouse,
|
mouse: Mouse,
|
||||||
resize_tx: mpsc::Sender<(u32, u32)>,
|
resize_tx: mpsc::Sender<LogicalSize>,
|
||||||
ref_test: bool,
|
ref_test: bool,
|
||||||
size_info: SizeInfo,
|
size_info: SizeInfo,
|
||||||
pub selection: Option<Selection>,
|
pub selection: Option<Selection>,
|
||||||
|
@ -247,7 +248,7 @@ impl<N: Notify> Processor<N> {
|
||||||
/// pty.
|
/// pty.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
notifier: N,
|
notifier: N,
|
||||||
resize_tx: mpsc::Sender<(u32, u32)>,
|
resize_tx: mpsc::Sender<LogicalSize>,
|
||||||
options: &Options,
|
options: &Options,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
ref_test: bool,
|
ref_test: bool,
|
||||||
|
@ -282,7 +283,7 @@ impl<N: Notify> Processor<N> {
|
||||||
processor: &mut input::Processor<'a, ActionContext<'a, N>>,
|
processor: &mut input::Processor<'a, ActionContext<'a, N>>,
|
||||||
event: Event,
|
event: Event,
|
||||||
ref_test: bool,
|
ref_test: bool,
|
||||||
resize_tx: &mpsc::Sender<(u32, u32)>,
|
resize_tx: &mpsc::Sender<LogicalSize>,
|
||||||
hide_cursor: &mut bool,
|
hide_cursor: &mut bool,
|
||||||
window_is_focused: &mut bool,
|
window_is_focused: &mut bool,
|
||||||
) {
|
) {
|
||||||
|
@ -315,8 +316,8 @@ impl<N: Notify> Processor<N> {
|
||||||
// FIXME should do a more graceful shutdown
|
// FIXME should do a more graceful shutdown
|
||||||
::std::process::exit(0);
|
::std::process::exit(0);
|
||||||
},
|
},
|
||||||
Resized(w, h) => {
|
Resized(lsize) => {
|
||||||
resize_tx.send((w, h)).expect("send new size");
|
resize_tx.send(lsize).expect("send new size");
|
||||||
processor.ctx.terminal.dirty = true;
|
processor.ctx.terminal.dirty = true;
|
||||||
},
|
},
|
||||||
KeyboardInput { input, .. } => {
|
KeyboardInput { input, .. } => {
|
||||||
|
@ -337,11 +338,10 @@ impl<N: Notify> Processor<N> {
|
||||||
processor.ctx.terminal.dirty = true;
|
processor.ctx.terminal.dirty = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CursorMoved { position: (x, y), modifiers, .. } => {
|
CursorMoved { position: lpos, modifiers, .. } => {
|
||||||
let x = x as i32;
|
let (x, y) = lpos.into();
|
||||||
let y = y as i32;
|
let x: i32 = limit(x, 0, processor.ctx.size_info.width as i32);
|
||||||
let x = limit(x, 0, processor.ctx.size_info.width as i32);
|
let y: i32 = limit(y, 0, processor.ctx.size_info.height as i32);
|
||||||
let y = limit(y, 0, processor.ctx.size_info.height as i32);
|
|
||||||
|
|
||||||
*hide_cursor = false;
|
*hide_cursor = false;
|
||||||
processor.mouse_moved(x as u32, y as u32, modifiers);
|
processor.mouse_moved(x as u32, y as u32, modifiers);
|
||||||
|
|
|
@ -456,14 +456,15 @@ impl<'a, A: ActionContext + 'a> Processor<'a, A> {
|
||||||
|
|
||||||
self.ctx.mouse_mut().lines_scrolled = to_scroll % 1.0;
|
self.ctx.mouse_mut().lines_scrolled = to_scroll % 1.0;
|
||||||
},
|
},
|
||||||
MouseScrollDelta::PixelDelta(_x, y) => {
|
MouseScrollDelta::PixelDelta(lpos) => {
|
||||||
match phase {
|
match phase {
|
||||||
TouchPhase::Started => {
|
TouchPhase::Started => {
|
||||||
// Reset offset to zero
|
// Reset offset to zero
|
||||||
self.ctx.mouse_mut().scroll_px = 0;
|
self.ctx.mouse_mut().scroll_px = 0;
|
||||||
},
|
},
|
||||||
TouchPhase::Moved => {
|
TouchPhase::Moved => {
|
||||||
self.ctx.mouse_mut().scroll_px += y as i32;
|
let (_x, y): (i32, i32) = lpos.into();
|
||||||
|
self.ctx.mouse_mut().scroll_px += y;
|
||||||
let height = self.ctx.size_info().cell_height as i32;
|
let height = self.ctx.size_info().cell_height as i32;
|
||||||
|
|
||||||
while self.ctx.mouse_mut().scroll_px.abs() >= height {
|
while self.ctx.mouse_mut().scroll_px.abs() >= height {
|
||||||
|
|
|
@ -79,6 +79,9 @@ use std::ops::Mul;
|
||||||
pub use grid::Grid;
|
pub use grid::Grid;
|
||||||
pub use term::Term;
|
pub use term::Term;
|
||||||
|
|
||||||
|
/// Re-export size and position types from glutin/winit
|
||||||
|
pub use glutin::dpi::{PhysicalSize,LogicalSize,LogicalPosition,PhysicalPosition};
|
||||||
|
|
||||||
/// Facade around [winit's `MouseCursor`](glutin::MouseCursor)
|
/// Facade around [winit's `MouseCursor`](glutin::MouseCursor)
|
||||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||||
pub enum MouseCursor {
|
pub enum MouseCursor {
|
||||||
|
|
|
@ -31,9 +31,7 @@ use notify::{Watcher, watcher, RecursiveMode, DebouncedEvent};
|
||||||
|
|
||||||
use config::{self, Config, Delta};
|
use config::{self, Config, Delta};
|
||||||
use term::{self, cell, RenderableCell};
|
use term::{self, cell, RenderableCell};
|
||||||
use window::{Size, Pixels};
|
use {PhysicalSize, Rgb};
|
||||||
|
|
||||||
use Rgb;
|
|
||||||
|
|
||||||
// Shader paths for live reload
|
// Shader paths for live reload
|
||||||
static TEXT_SHADER_F_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.f.glsl");
|
static TEXT_SHADER_F_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/res/text.f.glsl");
|
||||||
|
@ -476,7 +474,7 @@ const ATLAS_SIZE: i32 = 1024;
|
||||||
|
|
||||||
impl QuadRenderer {
|
impl QuadRenderer {
|
||||||
// TODO should probably hand this a transform instead of width/height
|
// TODO should probably hand this a transform instead of width/height
|
||||||
pub fn new(config: &Config, size: Size<Pixels<u32>>) -> Result<QuadRenderer, Error> {
|
pub fn new(config: &Config, size: PhysicalSize) -> Result<QuadRenderer, Error> {
|
||||||
let program = ShaderProgram::new(config, size)?;
|
let program = ShaderProgram::new(config, size)?;
|
||||||
|
|
||||||
let mut vao: GLuint = 0;
|
let mut vao: GLuint = 0;
|
||||||
|
@ -636,10 +634,7 @@ impl QuadRenderer {
|
||||||
while let Ok(msg) = self.rx.try_recv() {
|
while let Ok(msg) = self.rx.try_recv() {
|
||||||
match msg {
|
match msg {
|
||||||
Msg::ShaderReload => {
|
Msg::ShaderReload => {
|
||||||
self.reload_shaders(config, Size {
|
self.reload_shaders(config, PhysicalSize::new(props.width as f64, props.height as f64));
|
||||||
width: Pixels(props.width as u32),
|
|
||||||
height: Pixels(props.height as u32)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -690,7 +685,7 @@ impl QuadRenderer {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reload_shaders(&mut self, config: &Config, size: Size<Pixels<u32>>) {
|
pub fn reload_shaders(&mut self, config: &Config, size: PhysicalSize) {
|
||||||
warn!("Reloading shaders ...");
|
warn!("Reloading shaders ...");
|
||||||
let program = match ShaderProgram::new(config, size) {
|
let program = match ShaderProgram::new(config, size) {
|
||||||
Ok(program) => {
|
Ok(program) => {
|
||||||
|
@ -718,13 +713,15 @@ impl QuadRenderer {
|
||||||
self.program = program;
|
self.program = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, width: i32, height: i32) {
|
pub fn resize(&mut self, size: PhysicalSize) {
|
||||||
|
let (width, height) : (u32, u32) = size.into();
|
||||||
|
|
||||||
let padding_x = i32::from(self.program.padding_x);
|
let padding_x = i32::from(self.program.padding_x);
|
||||||
let padding_y = i32::from(self.program.padding_y);
|
let padding_y = i32::from(self.program.padding_y);
|
||||||
|
|
||||||
// viewport
|
// viewport
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::Viewport(padding_x, padding_y, width - 2 * padding_x, height - 2 * padding_y);
|
gl::Viewport(padding_x, padding_y, (width as i32) - 2 * padding_x, (height as i32) - 2 * padding_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update projection
|
// update projection
|
||||||
|
@ -953,7 +950,7 @@ impl ShaderProgram {
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
size: Size<Pixels<u32>>
|
size: PhysicalSize
|
||||||
) -> Result<ShaderProgram, ShaderCreationError> {
|
) -> Result<ShaderProgram, ShaderCreationError> {
|
||||||
let vertex_source = if cfg!(feature = "live-shader-reload") {
|
let vertex_source = if cfg!(feature = "live-shader-reload") {
|
||||||
None
|
None
|
||||||
|
@ -1021,7 +1018,7 @@ impl ShaderProgram {
|
||||||
padding_y: config.padding().y,
|
padding_y: config.padding().y,
|
||||||
};
|
};
|
||||||
|
|
||||||
shader.update_projection(*size.width as f32, *size.height as f32);
|
shader.update_projection(size.width as f32, size.height as f32);
|
||||||
|
|
||||||
shader.deactivate();
|
shader.deactivate();
|
||||||
|
|
||||||
|
|
133
src/window.rs
133
src/window.rs
|
@ -12,15 +12,16 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::fmt::{self, Display};
|
use std::fmt::Display;
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use gl;
|
use gl;
|
||||||
use glutin::{self, ContextBuilder, ControlFlow, CursorState, Event, EventsLoop,
|
use glutin::{self, ContextBuilder, ControlFlow, Event, EventsLoop,
|
||||||
MouseCursor as GlutinMouseCursor, WindowBuilder};
|
MouseCursor as GlutinMouseCursor, WindowBuilder};
|
||||||
use glutin::GlContext;
|
use glutin::GlContext;
|
||||||
|
|
||||||
use MouseCursor;
|
|
||||||
|
use {LogicalPosition, LogicalSize, MouseCursor, PhysicalSize};
|
||||||
|
|
||||||
|
|
||||||
use cli::Options;
|
use cli::Options;
|
||||||
use config::WindowConfig;
|
use config::WindowConfig;
|
||||||
|
@ -81,83 +82,7 @@ pub struct DeviceProperties {
|
||||||
///
|
///
|
||||||
/// This will be 1. on standard displays and may have a different value on
|
/// This will be 1. on standard displays and may have a different value on
|
||||||
/// hidpi displays.
|
/// hidpi displays.
|
||||||
pub scale_factor: f32,
|
pub scale_factor: f64,
|
||||||
}
|
|
||||||
|
|
||||||
/// Size of the window
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct Size<T> {
|
|
||||||
pub width: T,
|
|
||||||
pub height: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Strongly typed Pixels unit
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct Pixels<T>(pub T);
|
|
||||||
|
|
||||||
/// Strongly typed Points unit
|
|
||||||
///
|
|
||||||
/// Points are like pixels but adjusted for DPI.
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct Points<T>(pub T);
|
|
||||||
|
|
||||||
pub trait ToPoints {
|
|
||||||
fn to_points(&self, scale: f32) -> Size<Points<u32>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToPoints for Size<Points<u32>> {
|
|
||||||
#[inline]
|
|
||||||
fn to_points(&self, _scale: f32) -> Size<Points<u32>> {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToPoints for Size<Pixels<u32>> {
|
|
||||||
fn to_points(&self, scale: f32) -> Size<Points<u32>> {
|
|
||||||
let width_pts = (*self.width as f32 / scale) as u32;
|
|
||||||
let height_pts = (*self.height as f32 / scale) as u32;
|
|
||||||
|
|
||||||
Size {
|
|
||||||
width: Points(width_pts),
|
|
||||||
height: Points(height_pts)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Display> Display for Size<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{} × {}", self.width, self.height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! deref_newtype {
|
|
||||||
($($src:ty),+) => {
|
|
||||||
$(
|
|
||||||
impl<T> Deref for $src {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deref_newtype! { Points<T>, Pixels<T> }
|
|
||||||
|
|
||||||
|
|
||||||
impl<T: Display> Display for Pixels<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}px", self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Display> Display for Points<T> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{}pts", self.0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::std::error::Error for Error {
|
impl ::std::error::Error for Error {
|
||||||
|
@ -208,7 +133,8 @@ fn create_gl_window(
|
||||||
) -> ::std::result::Result<glutin::GlWindow, glutin::CreationError> {
|
) -> ::std::result::Result<glutin::GlWindow, glutin::CreationError> {
|
||||||
let context = ContextBuilder::new()
|
let context = ContextBuilder::new()
|
||||||
.with_srgb(srgb)
|
.with_srgb(srgb)
|
||||||
.with_vsync(true);
|
.with_vsync(true)
|
||||||
|
.with_hardware_acceleration(None);
|
||||||
::glutin::GlWindow::new(window, context, event_loop)
|
::glutin::GlWindow::new(window, context, event_loop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,19 +189,21 @@ impl Window {
|
||||||
/// rasterization depend on DPI and scale factor.
|
/// rasterization depend on DPI and scale factor.
|
||||||
pub fn device_properties(&self) -> DeviceProperties {
|
pub fn device_properties(&self) -> DeviceProperties {
|
||||||
DeviceProperties {
|
DeviceProperties {
|
||||||
scale_factor: self.window.hidpi_factor(),
|
scale_factor: self.window.get_hidpi_factor(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inner_size_pixels(&self) -> Option<Size<Pixels<u32>>> {
|
pub fn inner_size_pixels(&self) -> Option<LogicalSize> {
|
||||||
self.window
|
self.window.get_inner_size()
|
||||||
.get_inner_size()
|
}
|
||||||
.map(|(w, h)| Size { width: Pixels(w), height: Pixels(h) })
|
|
||||||
|
pub fn set_inner_size(&mut self, size: LogicalSize) {
|
||||||
|
self.window.set_inner_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hidpi_factor(&self) -> f32 {
|
pub fn hidpi_factor(&self) -> f64 {
|
||||||
self.window.hidpi_factor()
|
self.window.get_hidpi_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -301,8 +229,8 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn resize(&self, width: u32, height: u32) {
|
pub fn resize(&self, size: PhysicalSize) {
|
||||||
self.window.resize(width, height);
|
self.window.resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Block waiting for events
|
/// Block waiting for events
|
||||||
|
@ -331,13 +259,7 @@ impl Window {
|
||||||
pub fn set_cursor_visible(&mut self, visible: bool) {
|
pub fn set_cursor_visible(&mut self, visible: bool) {
|
||||||
if visible != self.cursor_visible {
|
if visible != self.cursor_visible {
|
||||||
self.cursor_visible = visible;
|
self.cursor_visible = visible;
|
||||||
if let Err(err) = self.window.set_cursor_state(if visible {
|
self.window.hide_cursor(!visible);
|
||||||
CursorState::Normal
|
|
||||||
} else {
|
|
||||||
CursorState::Hide
|
|
||||||
}) {
|
|
||||||
warn!("Failed to set cursor visibility: {}", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,8 +283,8 @@ impl Window {
|
||||||
#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")))]
|
#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")))]
|
||||||
pub fn set_urgent(&self, _is_urgent: bool) {}
|
pub fn set_urgent(&self, _is_urgent: bool) {}
|
||||||
|
|
||||||
pub fn set_ime_spot(&self, x: i32, y: i32) {
|
pub fn set_ime_spot(&self, pos: LogicalPosition) {
|
||||||
self.window.set_ime_spot(x, y);
|
self.window.set_ime_spot(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
@ -439,14 +361,3 @@ impl Proxy {
|
||||||
self.inner.wakeup().unwrap();
|
self.inner.wakeup().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SetInnerSize<T> {
|
|
||||||
fn set_inner_size<S: ToPoints>(&mut self, size: &S);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SetInnerSize<Pixels<u32>> for Window {
|
|
||||||
fn set_inner_size<T: ToPoints>(&mut self, size: &T) {
|
|
||||||
let size = size.to_points(self.hidpi_factor());
|
|
||||||
self.window.set_inner_size(*size.width as _, *size.height as _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue