Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ You can find its changes [documented below](#082---2023-01-27).
### Added

- `foreground`, `set_foreground`, and `clear_foreground` methods to `Container` and `WidgetExt::foreground` method for convenience. ([#2346] by [@giannissc])
- `WindowHandle::hide` method to hide a window. ([#2191] by [@newcomb-luke])

### Changed

Expand Down Expand Up @@ -768,6 +769,7 @@ Last release without a changelog :(
[@lzhoucs]: https://github.com/lzhoucs
[@ratmice]: https://github.com/ratmice
[@giannissc]: https://github.com/giannissc
[@newcomb-luke]: https://github.com/newcomb-luke

[#599]: https://github.com/linebender/druid/pull/599
[#611]: https://github.com/linebender/druid/pull/611
Expand Down Expand Up @@ -1164,6 +1166,7 @@ Last release without a changelog :(
[#2157]: https://github.com/linebender/druid/pull/2157
[#2158]: https://github.com/linebender/druid/pull/2158
[#2172]: https://github.com/linebender/druid/pull/2172
[#2191]: https://github.com/linebender/druid/pull/2191
[#2195]: https://github.com/linebender/druid/pull/2195
[#2196]: https://github.com/linebender/druid/pull/2196
[#2203]: https://github.com/linebender/druid/pull/2203
Expand Down
7 changes: 7 additions & 0 deletions druid-shell/src/backend/gtk/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,13 @@ impl WindowHandle {
}
}

/// Hide the window
pub fn hide(&self) {
if let Some(state) = self.state.upgrade() {
state.window.hide();
}
}

/// Bring this window to the front of the window stack and give it focus.
pub fn bring_to_front_and_focus(&self) {
if let Some(state) = self.state.upgrade() {
Expand Down
8 changes: 8 additions & 0 deletions druid-shell/src/backend/mac/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,14 @@ impl WindowHandle {
}
}

/// Hide the window.
pub fn hide(&self) {
unsafe {
let window: id = msg_send![*self.nsview.load(), window];
let () = msg_send![window, orderOut: self];
}
}

/// Bring this window to the front of the window stack and give it focus.
pub fn bring_to_front_and_focus(&self) {
unsafe {
Expand Down
7 changes: 6 additions & 1 deletion druid-shell/src/backend/wayland/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,14 @@ impl WindowHandle {
}
}

/// Hide the window.
pub fn hide(&self) {
tracing::warn!("hide is unimplemented on wayland");
}

/// Bring this window to the front of the window stack and give it focus.
pub fn bring_to_front_and_focus(&self) {
tracing::warn!("unimplemented bring_to_front_and_focus initiated");
tracing::warn!("bring_to_front_and_focus is unimplemented on wayland");
}

/// Request a new paint, but without invalidating anything.
Expand Down
4 changes: 4 additions & 0 deletions druid-shell/src/backend/web/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,10 @@ impl WindowHandle {
// TODO
}

pub fn hide(&self) {
warn!("hide unimplemented for web");
}

pub fn bring_to_front_and_focus(&self) {
warn!("bring_to_frontand_focus unimplemented for web");
}
Expand Down
24 changes: 22 additions & 2 deletions druid-shell/src/backend/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ enum DeferredOp {
SetSize(Size),
SetResizable(bool),
SetWindowState(window::WindowState),
ShowWindow(bool),
ReleaseMouseCapture,
}

Expand Down Expand Up @@ -618,6 +619,17 @@ impl MyWndProc {
ShowWindow(hwnd, show);
}
}
DeferredOp::ShowWindow(should_show) => {
let show = if should_show { SW_SHOW } else { SW_HIDE };

unsafe {
ShowWindow(hwnd, show);

if should_show {
SetForegroundWindow(hwnd);
}
}
}
DeferredOp::SaveAs(options, token) => {
let info = unsafe {
get_file_dialog_path(hwnd, FileDialogType::Save, options)
Expand Down Expand Up @@ -758,6 +770,9 @@ impl WndProc for MyWndProc {
Some(0)
}
WM_ACTIVATE => {
// Check if the low-order word is not 0
// If it were 0, then that means we are being deactivated, in which case we do nothing.
// If it is != 0, then we have been activated.
if LOWORD(wparam as u32) as u32 != 0 {
unsafe {
if !self.has_titlebar() && !self.is_transparent() {
Expand Down Expand Up @@ -1850,6 +1865,7 @@ impl WindowHandle {
}
}

/// Closes the window.
pub fn close(&self) {
if let Some(w) = self.state.upgrade() {
let hwnd = w.hwnd.get();
Expand All @@ -1859,10 +1875,14 @@ impl WindowHandle {
}
}

/// Hides the window.
pub fn hide(&self) {
self.defer(DeferredOp::ShowWindow(false));
}

/// Bring this window to the front of the window stack and give it focus.
pub fn bring_to_front_and_focus(&self) {
//FIXME: implementation goes here
warn!("bring_to_front_and_focus not yet implemented on windows");
self.defer(DeferredOp::ShowWindow(true));
}

pub fn request_anim_frame(&self) {
Expand Down
21 changes: 20 additions & 1 deletion druid-shell/src/backend/x11/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,12 @@ impl Window {
}
}

fn hide(&self) {
if !self.destroyed() {
log_x11!(self.app.connection().unmap_window(self.id));
}
}

fn close(&self) {
self.destroy();
}
Expand Down Expand Up @@ -922,12 +928,17 @@ impl Window {
return;
}

// TODO(x11/misc): Unsure if this does exactly what the doc comment says; need a test case.
let conn = self.app.connection();

// This has no effect if we are already "mapped" but it shows the application if it was previously hidden
log_x11!(conn.map_window(self.id));

// Ask nicely to have our window to be at the top of the window stack
log_x11!(conn.configure_window(
self.id,
&xproto::ConfigureWindowAux::new().stack_mode(xproto::StackMode::ABOVE),
));

log_x11!(conn.set_input_focus(
xproto::InputFocus::POINTER_ROOT,
self.id,
Expand Down Expand Up @@ -1609,6 +1620,14 @@ impl WindowHandle {
}
}

pub fn hide(&self) {
if let Some(w) = self.window.upgrade() {
w.hide();
} else {
error!("Window {} has already been dropped", self.id);
}
}

pub fn close(&self) {
if let Some(w) = self.window.upgrade() {
w.close();
Expand Down
8 changes: 5 additions & 3 deletions druid-shell/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ pub struct WindowHandle(pub(crate) backend::WindowHandle);

impl WindowHandle {
/// Make this window visible.
///
/// This is part of the initialization process; it should only be called
/// once, when a window is first created.
pub fn show(&self) {
self.0.show()
}
Expand All @@ -186,6 +183,11 @@ impl WindowHandle {
self.0.close()
}

/// Hide the window
pub fn hide(&self) {
self.0.hide()
}

/// Set whether the window should be resizable
pub fn resizable(&self, resizable: bool) {
self.0.resizable(resizable)
Expand Down
7 changes: 7 additions & 0 deletions druid/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ pub mod sys {
/// will automatically target the window containing the widget.
pub const SHOW_WINDOW: Selector = Selector::new("druid-builtin.show-window");

/// The selector for a command to hide a specific window
///
/// The command must target a specific window.
/// When calling `submit_command` on a `Widget`s context, passing `None` as target
/// will automatically target the window containing the widget.
pub const HIDE_WINDOW: Selector = Selector::new("druid-builtin.hide-window");

/// Apply the configuration payload to an existing window. The target should be a WindowId.
pub const CONFIGURE_WINDOW: Selector<WindowConfig> =
Selector::new("druid-builtin.configure-window");
Expand Down
14 changes: 14 additions & 0 deletions druid/src/win_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,12 @@ impl<T: Data> InnerAppState<T> {
}
}

fn hide_window(&mut self, id: WindowId) {
if let Some(win) = self.windows.get_mut(id) {
win.handle.hide();
}
}

fn configure_window(&mut self, config: &WindowConfig, id: WindowId) {
if let Some(win) = self.windows.get_mut(id) {
config.apply_to_handle(&mut win.handle);
Expand Down Expand Up @@ -689,13 +695,17 @@ impl<T: Data> AppState<T> {
}
}
T::Window(id) if cmd.is(sys_cmd::SHOW_WINDOW) => self.show_window(id),
T::Window(id) if cmd.is(sys_cmd::HIDE_WINDOW) => self.hide_window(id),
T::Window(id) if cmd.is(sys_cmd::PASTE) => self.do_paste(id),
_ if cmd.is(sys_cmd::CLOSE_WINDOW) => {
tracing::warn!("CLOSE_WINDOW command must target a window.")
}
_ if cmd.is(sys_cmd::SHOW_WINDOW) => {
tracing::warn!("SHOW_WINDOW command must target a window.")
}
_ if cmd.is(sys_cmd::HIDE_WINDOW) => {
tracing::warn!("HIDE_WINDOW command must target a window.")
}
_ if cmd.is(sys_cmd::SHOW_OPEN_PANEL) => {
tracing::warn!("SHOW_OPEN_PANEL command must target a window.")
}
Expand Down Expand Up @@ -848,6 +858,10 @@ impl<T: Data> AppState<T> {
self.inner.borrow_mut().show_window(id);
}

fn hide_window(&mut self, id: WindowId) {
self.inner.borrow_mut().hide_window(id);
}

fn configure_window(&mut self, cmd: Command, id: WindowId) {
if let Some(config) = cmd.get(sys_cmd::CONFIGURE_WINDOW) {
self.inner.borrow_mut().configure_window(config, id);
Expand Down