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

Screen Module, window titlebar, position, size, DPI #1037

Merged
merged 21 commits into from
Sep 11, 2020
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@ You can find its changes [documented below](#060---2020-06-01).

### Added

- Windows: Added Screen module to get information about monitors and the screen. ([#1037] by [@rhzk])
- Added documentation to resizable() and show_titlebar() in WindowDesc. ([#1037] by [@rhzk])
- Windows: Added internal functions to handle Re-entrancy. ([#1037] by [@rhzk])
- Windows: WindowDesc: Create window with disabled titlebar, maximized or minimized and with position. ([#1037] by [@rhzk])
- Windows: WindowHandle: Toggle maximize, minimize window. Toggle titlebar. Change size and position of window. ([#1037] by [@rhzk])
- Windows: WindowHandle: Added handle_titlebar(), Allowing a custom titlebar to behave like the OS one. ([#1037] by [@rhzk])
- Added ctrl/shift key support to textbox. ([#1063] by [@vkahl])

### Changed

- Windows: Improved DPI handling. Druid should now redraw correctly when dpi changes. ([#1037] by [@rhzk])
- winOS: Window created with OS default size if not set. ([#1037] by [@rhzk])
- `Image` and `ImageData` exported by default. ([#1011] by [@covercash2])
- `Scale::from_scale` to `Scale::new`, and `Scale` methods `scale_x` / `scale_y` to `x` / `y`. ([#1042] by [@xStrom])
- Major rework of keyboard event handling ([#1049] by [@raphlinus])
Expand Down Expand Up @@ -222,6 +230,7 @@ Last release without a changelog :(
## 0.1.1 - 2018-11-02
## 0.1.0 - 2018-11-02

[@rhzk]: https://github.com/rhzk
[@futurepaul]: https://github.com/futurepaul
[@finnerale]: https://github.com/finnerale
[@totsteps]: https://github.com/totsteps
Expand Down Expand Up @@ -359,6 +368,7 @@ Last release without a changelog :(
[#1062]: https://github.com/linebender/druid/pull/1062
[#1072]: https://github.com/linebender/druid/pull/1072
[#1081]: https://github.com/linebender/druid/pull/1081
[#1037]: https://github.com/linebender/druid/pull/1037

[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: 1 addition & 2 deletions druid-shell/src/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@ pub enum FileDialogType {
}

/// Options for file dialogs.
#[non_exhaustive]
#[derive(Debug, Clone, Default)]
pub struct FileDialogOptions {
pub show_hidden: bool,
pub allowed_types: Option<Vec<FileSpec>>,
pub default_type: Option<FileSpec>,
pub select_directories: bool,
pub multi_selection: bool,
// we don't want a library user to be able to construct this type directly
__non_exhaustive: (),
}

/// A description of a filetype, for specifiying allowed types in a file dialog.
Expand Down
3 changes: 3 additions & 0 deletions druid-shell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ mod menu;
mod mouse;
mod platform;
mod scale;
mod screen;
mod window;

pub use application::{AppHandler, Application};
Expand All @@ -59,6 +60,8 @@ pub use keyboard::{Code, IntoKey, KbKey, KeyEvent, KeyState, Location, Modifiers
pub use menu::Menu;
pub use mouse::{Cursor, MouseButton, MouseButtons, MouseEvent};
pub use scale::{Scalable, Scale, ScaledArea};
pub use screen::Monitor;
pub use screen::Screen;
pub use window::{
IdleHandle, IdleToken, Text, TimerToken, WinHandler, WindowBuilder, WindowHandle,
};
Expand Down
1 change: 1 addition & 0 deletions druid-shell/src/platform/gtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ pub mod keycodes;
pub mod menu;
pub mod util;
pub mod window;
pub mod screen;
28 changes: 28 additions & 0 deletions druid-shell/src/platform/gtk/screen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020 The Druid Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! GTK Monitors and Screen information.

use crate::screen::Monitor;
use crate::kurbo::Size;

pub(crate) fn get_display_size() -> Size {
log::warn!("Screen::get_display_size() is currently unimplemented for gtk.");
Size::new(0.0, 0.0)
}

pub(crate) fn get_monitors() -> Vec<Monitor> {
log::warn!("Screen::get_monitors() is currently unimplemented for gtk.");
Vec::<Monitor>::new()
}
42 changes: 42 additions & 0 deletions druid-shell/src/platform/gtk/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,18 @@ impl WindowBuilder {
self.show_titlebar = show_titlebar;
}

pub fn set_position(&mut self, _position: Point) {
log::warn!("WindowBuilder::set_position is currently unimplemented for gtk.");
}

pub fn maximized(&self) {
log::warn!("WindowBuilder::maximized is currently unimplemented for gtk.");
}

pub fn minimized(&self) {
log::warn!("WindowBuilder::minimized is currently unimplemented for gtk.");
}

pub fn set_title(&mut self, title: impl Into<String>) {
self.title = title.into();
}
Expand Down Expand Up @@ -553,6 +565,36 @@ impl WindowHandle {
}
}

pub fn set_position(&self, _position: Point) {
log::warn!("WindowHandle::set_position is currently unimplemented for gtk.");
}

pub fn get_position(&self) -> Point {
log::warn!("WindowHandle::get_position is currently unimplemented for gtk.");
Point::new(0.0, 0.0)
}

pub fn set_size(&self, _size: Size) {
log::warn!("WindowHandle::set_size is currently unimplemented for gtk.");
}

pub fn get_size(&self) -> Size {
log::warn!("WindowHandle::get_size is currently unimplemented for gtk.");
Size::new(0.0, 0.0)
}

pub fn maximize(&self) {
log::warn!("WindowHandle::maximize is currently unimplemented for gtk.");
}

pub fn minimize(&self) {
log::warn!("WindowHandle::minimize is currently unimplemented for gtk.");
}

pub fn handle_titlebar(&self, _val: bool) {
log::warn!("WindowHandle::handle_titlebar is currently unimplemented for gtk.");
}

/// Close the window.
pub fn close(&self) {
if let Some(state) = self.state.upgrade() {
Expand Down
1 change: 1 addition & 0 deletions druid-shell/src/platform/mac/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ mod keyboard;
pub mod menu;
pub mod util;
pub mod window;
pub mod screen;
28 changes: 28 additions & 0 deletions druid-shell/src/platform/mac/screen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020 The Druid Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! macOS Monitors and Screen information.

use crate::screen::Monitor;
use crate::kurbo::Size;

pub(crate) fn get_display_size() -> Size {
log::warn!("Screen::get_display_size() is currently unimplemented for Mac.");
Size::new(0.0, 0.0)
}

pub(crate) fn get_monitors() -> Vec<Monitor> {
log::warn!("Screen::get_monitors() is currently unimplemented for Mac.");
Vec::<Monitor>::new()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this needs a turbofish. Also note, the pattern appears in the other stub implementations.

}
42 changes: 42 additions & 0 deletions druid-shell/src/platform/mac/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,18 @@ impl WindowBuilder {
self.show_titlebar = show_titlebar;
}

pub fn set_position(&mut self, _position: Point) {
log::warn!("WindowBuilder::set_position is currently unimplemented for mac platforms.");
}

pub fn maximized(&self) {
log::warn!("WindowBuilder::maximized is currently unimplemented for mac platforms.");
}

pub fn minimized(&self) {
log::warn!("WindowBuilder::minimized is currently unimplemented for mac platforms.");
}

pub fn set_title(&mut self, title: impl Into<String>) {
self.title = title.into();
}
Expand Down Expand Up @@ -838,6 +850,36 @@ impl WindowHandle {
// TODO: Implement this
pub fn show_titlebar(&self, _show_titlebar: bool) {}

pub fn set_position(&self, _position: Point) {
log::warn!("WindowHandle::set_position is currently unimplemented for Mac.");
}

pub fn get_position(&self) -> Point {
log::warn!("WindowHandle::get_position is currently unimplemented for Mac.");
Point::new(0.0, 0.0)
}

pub fn set_size(&self, _size: Size) {
log::warn!("WindowHandle::set_size is currently unimplemented for Mac.");
}

pub fn get_size(&self) -> Size {
log::warn!("WindowHandle::get_size is currently unimplemented for Mac.");
Size::new(0.0, 0.0)
}

pub fn maximize(&self) {
log::warn!("WindowHandle::maximize is currently unimplemented for Mac.");
}

pub fn minimize(&self) {
log::warn!("WindowHandle::minimize is currently unimplemented for Mac.");
}

pub fn handle_titlebar(&self, _val: bool) {
log::warn!("WindowHandle::handle_titlebar is currently unimplemented for Mac.");
}

pub fn resizable(&self, resizable: bool) {
unsafe {
let window: id = msg_send![*self.nsview.load(), window];
Expand Down
1 change: 1 addition & 0 deletions druid-shell/src/platform/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ pub mod error;
pub mod keycodes;
pub mod menu;
pub mod window;
pub mod screen;
28 changes: 28 additions & 0 deletions druid-shell/src/platform/web/screen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020 The Druid Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Monitor and Screen information ignored for web.

use crate::screen::Monitor;
use crate::kurbo::Size;

pub(crate) fn get_display_size() -> Size {
log::warn!("Screen::get_display_size() is not implemented for web.");
Size::new(0.0, 0.0)
}

pub(crate) fn get_monitors() -> Vec<Monitor> {
log::warn!("Screen::get_monitors() is not implemented for web.");
Vec::<Monitor>::new()
}
42 changes: 42 additions & 0 deletions druid-shell/src/platform/web/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,18 @@ impl WindowBuilder {
// Ignored
}

pub fn set_position(&mut self, _position: Point) {
// Ignored
}

pub fn maximized(&self) {
// Ignored
}

pub fn minimized(&self) {
// Ignored
}

pub fn set_title<S: Into<String>>(&mut self, title: S) {
self.title = title.into();
}
Expand Down Expand Up @@ -430,6 +442,36 @@ impl WindowHandle {
log::warn!("show_titlebar unimplemented for web");
}

pub fn set_position(&self, _position: Point) {
log::warn!("WindowHandle::set_position unimplemented for web");
}

pub fn get_position(&self) -> Point {
log::warn!("WindowHandle::get_position unimplemented for web.");
Point::new(0.0, 0.0)
}

pub fn set_size(&self, _size: Size) {
log::warn!("WindowHandle::set_size unimplemented for web.");
}

pub fn get_size(&self) -> Size {
log::warn!("WindowHandle::get_size unimplemented for web.");
Size::new(0.0, 0.0)
}

pub fn maximize(&self) {
log::warn!("WindowHandle::maximize unimplemented for web.");
}

pub fn minimize(&self) {
log::warn!("WindowHandle::minimize unimplemented for web.");
}

pub fn handle_titlebar(&self, _val: bool) {
log::warn!("WindowHandle::handle_titlebar unimplemented for web.");
}

pub fn close(&self) {
// TODO
}
Expand Down
16 changes: 10 additions & 6 deletions druid-shell/src/platform/windows/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ use std::rc::Rc;

use winapi::shared::minwindef::{FALSE, HINSTANCE};
use winapi::shared::ntdef::LPCWSTR;
use winapi::shared::windef::{HCURSOR, HWND};
use winapi::shared::windef::{HCURSOR, HWND, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2};
use winapi::shared::winerror::HRESULT_FROM_WIN32;
use winapi::um::errhandlingapi::GetLastError;
use winapi::um::shellscalingapi::PROCESS_SYSTEM_DPI_AWARE;
use winapi::um::winuser::{
DispatchMessageW, GetAncestor, GetMessageW, LoadIconW, PostMessageW, PostQuitMessage,
RegisterClassW, TranslateAcceleratorW, TranslateMessage, GA_ROOT, IDI_APPLICATION, MSG,
WNDCLASSW,
WNDCLASSW, SendMessageW
};

use crate::application::AppHandler;
Expand All @@ -38,7 +37,7 @@ use super::accels;
use super::clipboard::Clipboard;
use super::error::Error;
use super::util::{self, ToWide, CLASS_NAME, OPTIONAL_FUNCTIONS};
use super::window::{self, DS_REQUEST_DESTROY};
use super::window::{self, DS_REQUEST_DESTROY, DS_HANDLE_DROPPED};

#[derive(Clone)]
pub(crate) struct Application {
Expand All @@ -64,10 +63,10 @@ impl Application {
fn init() -> Result<(), Error> {
// TODO: Report back an error instead of panicking
util::attach_console();
if let Some(func) = OPTIONAL_FUNCTIONS.SetProcessDpiAwareness {
if let Some(func) = OPTIONAL_FUNCTIONS.SetProcessDpiAwarenessContext {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do have a concern here. The old implementation worked on Windows 8.1 (the comment was wrong), now it seems like there won't be any dpi.

A related concern is that this function will fail on Windows 10 versions previous to 1703, and will result in no dpi scaling. I think fallback handling based on the optional function should take care of this though.

Also, we should probably at least log an error return value, though I think runtime failure is not likely. That's certainly on me from the old code though :)

// This function is only supported on windows 10
unsafe {
func(PROCESS_SYSTEM_DPI_AWARE); // TODO: per monitor (much harder)
func(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}
}
unsafe {
Expand Down Expand Up @@ -105,6 +104,11 @@ impl Application {
unsafe {
// Handle windows messages
loop {
if let Ok(state) = self.state.try_borrow() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My experience is that putting any additional functionality in the runloop is problematic. The logic doesn't get invoked when the system is using its own runloop, which happens on live resize and also while a file dialog is open. Also, if and when we ever run as a guest (for example as a VST plugin), then we'll also be at the mercy of the host's runloop. But if we use the function sparingly, maybe we're ok.

Also, I think the name "DS_HANDLE_DROPPED" is confusing and should be changed to "BLOCKED" to be consistent with other functions.

See below where I suggest a comment to add.

for hwnd in &state.windows {
SendMessageW(*hwnd, DS_HANDLE_DROPPED, 0,0);
}
}
rhzk marked this conversation as resolved.
Show resolved Hide resolved
let mut msg = mem::MaybeUninit::uninit();
let res = GetMessageW(msg.as_mut_ptr(), ptr::null_mut(), 0, 0);
if res <= 0 {
Expand Down
Loading