Skip to content

Commit

Permalink
Merge pull request #1231 from rjwittams/window-level
Browse files Browse the repository at this point in the history
Introduce WindowLevel, plus Mac and GTK implementations.
  • Loading branch information
rjwittams authored Sep 14, 2020
2 parents bd6e08d + a3e7690 commit a0693f9
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 48 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ You can find its changes [documented below](#060---2020-06-01).
- `TextAlignment` support in `TextLayout` and `Label` ([#1210] by [@cmyr])`
- `Button::from_label` to construct a `Button` with a provided `Label`. ([#1226] by [@ForLoveOfCats])
- Lens: Added Unit lens for type erased / display only widgets that do not need data. ([#1232] by [@rjwittams])
- `WindowLevel` to control system window Z order, with Mac and GTK implementations ([#1231] by [@rjwittams])

### Changed

Expand Down Expand Up @@ -451,6 +452,7 @@ Last release without a changelog :(
[#1214]: https://github.com/linebender/druid/pull/1214
[#1226]: https://github.com/linebender/druid/pull/1226
[#1232]: https://github.com/linebender/druid/pull/1232
[#1231]: https://github.com/linebender/druid/pull/1231

[Unreleased]: https://github.com/linebender/druid/compare/v0.6.0...master
[0.6.0]: https://github.com/linebender/druid/compare/v0.5.0...v0.6.0
Expand Down
3 changes: 2 additions & 1 deletion druid-shell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ pub use region::Region;
pub use scale::{Scalable, Scale, ScaledArea};
pub use screen::{Monitor, Screen};
pub use window::{
IdleHandle, IdleToken, TimerToken, WinHandler, WindowBuilder, WindowHandle, WindowState,
IdleHandle, IdleToken, TimerToken, WinHandler, WindowBuilder, WindowHandle, WindowLevel,
WindowState,
};

pub use keyboard_types;
50 changes: 36 additions & 14 deletions druid-shell/src/platform/gtk/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use std::time::Instant;

use anyhow::anyhow;
use cairo::Surface;
use gdk::{EventKey, EventMask, ModifierType, ScrollDirection, WindowExt};
use gdk::{EventKey, EventMask, ModifierType, ScrollDirection, WindowExt, WindowTypeHint};
use gio::ApplicationExt;
use gtk::prelude::*;
use gtk::{AccelGroup, ApplicationWindow, DrawingArea};
Expand All @@ -42,8 +42,8 @@ use crate::keyboard::{KbKey, KeyEvent, KeyState, Modifiers};
use crate::mouse::{Cursor, MouseButton, MouseButtons, MouseEvent};
use crate::region::Region;
use crate::scale::{Scalable, Scale, ScaledArea};
use crate::window::{IdleToken, TimerToken, WinHandler};
use crate::window;
use crate::window::{IdleToken, TimerToken, WinHandler, WindowLevel};

use super::application::Application;
use super::dialog;
Expand Down Expand Up @@ -98,6 +98,7 @@ pub(crate) struct WindowBuilder {
title: String,
menu: Option<Menu>,
position: Option<Point>,
level: Option<WindowLevel>,
state: Option<window::WindowState>,
size: Size,
min_size: Option<Size>,
Expand Down Expand Up @@ -154,6 +155,7 @@ impl WindowBuilder {
menu: None,
size: Size::new(500.0, 400.0),
position: None,
level: None,
state: None,
min_size: None,
resizable: true,
Expand Down Expand Up @@ -185,6 +187,10 @@ impl WindowBuilder {
self.position = Some(position);
}

pub fn set_level(&mut self, level: WindowLevel) {
self.level = Some(level);
}

pub fn set_window_state(&mut self, state: window::WindowState) {
self.state = Some(state);
}
Expand Down Expand Up @@ -250,6 +256,9 @@ impl WindowBuilder {
let mut handle = WindowHandle {
state: Arc::downgrade(&win_state),
};
if let Some(level) = self.level {
handle.set_level(level);
}
if let Some(pos) = self.position {
handle.set_position(pos);
}
Expand Down Expand Up @@ -692,56 +701,69 @@ impl WindowHandle {
}

pub fn get_position(&self) -> Point {
if let Some(state) = self.state.upgrade(){
if let Some(state) = self.state.upgrade() {
let (x, y) = state.window.get_position();
Point::new(x as f64, y as f64)
}else{
} else {
Point::new(0.0, 0.0)
}
}

pub fn set_level(&self, level: WindowLevel) {
if let Some(state) = self.state.upgrade() {
let hint = match level {
WindowLevel::AppWindow => WindowTypeHint::Normal,
WindowLevel::Tooltip => WindowTypeHint::Tooltip,
WindowLevel::DropDown => WindowTypeHint::DropdownMenu,
WindowLevel::Modal => WindowTypeHint::Dialog,
};

state.window.set_type_hint(hint);
}
}

pub fn set_size(&self, size: Size) {
if let Some(state) = self.state.upgrade(){
if let Some(state) = self.state.upgrade() {
state.window.resize(size.width as i32, size.height as i32)
}
}

pub fn get_size(&self) -> Size {
if let Some(state) = self.state.upgrade(){
if let Some(state) = self.state.upgrade() {
let (x, y) = state.window.get_size();
Size::new(x as f64, y as f64)
} else{
} else {
log::warn!("Could not get size for GTK window");
Size::new(0. , 0.)
Size::new(0., 0.)
}
}

pub fn set_window_state(&mut self, size_state: window::WindowState) {
use window::WindowState::{MINIMIZED, MAXIMIZED, RESTORED};
use window::WindowState::{MAXIMIZED, MINIMIZED, RESTORED};
let cur_size_state = self.get_window_state();
if let Some(state) = self.state.upgrade(){
if let Some(state) = self.state.upgrade() {
match (size_state, cur_size_state) {
(s1, s2) if s1 == s2 => (),
(MAXIMIZED, _) => state.window.maximize(),
(MINIMIZED, _) => state.window.iconify(),
(RESTORED, MAXIMIZED) => state.window.unmaximize(),
(RESTORED, MINIMIZED) => state.window.deiconify(),
(RESTORED, RESTORED) => () // Unreachable
(RESTORED, RESTORED) => (), // Unreachable
}

state.window.unmaximize();
}
}

pub fn get_window_state(&self) -> window::WindowState {
use window::WindowState::{MINIMIZED, MAXIMIZED, RESTORED};
use window::WindowState::{MAXIMIZED, MINIMIZED, RESTORED};
if let Some(state) = self.state.upgrade() {
if state.window.is_maximized() {
return MAXIMIZED
return MAXIMIZED;
} else if let Some(window) = state.window.get_parent_window() {
let state = window.get_state();
if (state & gdk::WindowState::ICONIFIED) == gdk::WindowState::ICONIFIED {
return MINIMIZED
return MINIMIZED;
}
}
}
Expand Down
Loading

0 comments on commit a0693f9

Please sign in to comment.