diff --git a/v3/STATUS.md b/v3/STATUS.md index c7c6b40d1..9313ef233 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -82,8 +82,8 @@ Webview Window Interface Methods | Feature | Windows | Linux | Mac | Notes | |---------|---------|-------|-----|-------| | Quit | | | Y | | -| Hide | | | Y | | -| Show | | | Y | | +| Hide | Y | | Y | | +| Show | Y | | Y | | ### Dialogs diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index 3f9225673..b85db6e4f 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -23,6 +23,10 @@ type windowsApp struct { mainThreadID w32.HANDLE mainThreadWindowHWND w32.HWND + // Windows hidden by application.Hide() + hiddenWindows []*windowsWebviewWindow + focusedWindow w32.HWND + // system theme isDarkMode bool } @@ -38,9 +42,29 @@ func (m *windowsApp) getScreens() ([]*Screen, error) { } func (m *windowsApp) hide() { + // Get the current focussed window + m.focusedWindow = w32.GetForegroundWindow() + + // Iterate over all windows and hide them if they aren't already hidden + for _, window := range m.windowMap { + if window.isVisible() { + // Add to hidden windows + m.hiddenWindows = append(m.hiddenWindows, window) + window.hide() + } + } + // Switch focus to the next application + hwndNext := w32.GetWindow(m.mainThreadWindowHWND, w32.GW_HWNDNEXT) + w32.SetForegroundWindow(hwndNext) } func (m *windowsApp) show() { + // Iterate over all windows and show them if they were previously hidden + for _, window := range m.hiddenWindows { + window.show() + } + // Show the foreground window + w32.SetForegroundWindow(m.focusedWindow) } func (m *windowsApp) on(eventID uint) { diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 638613b2d..423a9301a 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -53,7 +53,7 @@ type ( isMaximised() bool isFullscreen() bool isNormal() bool - disableSizeConstraints() + isVisible() bool setFullscreenButtonEnabled(enabled bool) show() hide() @@ -360,6 +360,14 @@ func (w *WebviewWindow) IsMinimised() bool { return w.impl.isMinimised() } +// IsVisible returns true if the window is visible +func (w *WebviewWindow) IsVisible() bool { + if w.impl == nil { + return false + } + return w.impl.isVisible() +} + // IsMaximised returns true if the window is maximised func (w *WebviewWindow) IsMaximised() bool { if w.impl == nil { diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 7e0bc76e6..9fcece222 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -260,6 +260,7 @@ func (w *windowsWebviewWindow) setPosition(x int, y int) { w32.SetWindowPos(w.hwnd, w32.HWND_TOP, int(workRect.Left)+x, int(workRect.Top)+y, 0, 0, w32.SWP_NOSIZE) } +// on is used to indicate that a particular event should be listened for func (w *windowsWebviewWindow) on(eventID uint) { //TODO implement me panic("implement me") @@ -320,14 +321,13 @@ func (w *windowsWebviewWindow) isNormal() bool { return !w.isMinimised() && !w.isMaximised() && !w.isFullscreen() } -func (w *windowsWebviewWindow) disableSizeConstraints() { - //TODO implement me - panic("implement me") +func (w *windowsWebviewWindow) isVisible() bool { + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_VISIBLE != 0 } -func (w *windowsWebviewWindow) setFullscreenButtonEnabled(enabled bool) { - //TODO implement me - panic("implement me") +func (w *windowsWebviewWindow) setFullscreenButtonEnabled(_ bool) { + // Unused in Windows } func (w *windowsWebviewWindow) show() { diff --git a/v3/pkg/w32/constants.go b/v3/pkg/w32/constants.go index 8105b1195..1b200046d 100644 --- a/v3/pkg/w32/constants.go +++ b/v3/pkg/w32/constants.go @@ -276,6 +276,16 @@ const ( GWLP_USERDATA = -21 ) +const ( + GW_HWNDFIRST = 0 + GW_HWNDLAST = 1 + GW_HWNDNEXT = 2 + GW_HWNDPREV = 3 + GW_OWNER = 4 + GW_CHILD = 5 + GW_ENABLEDPOPUP = 6 +) + // Window style constants const ( WS_OVERLAPPED = 0x00000000 diff --git a/v3/pkg/w32/user32.go b/v3/pkg/w32/user32.go index d337a6145..9357d2586 100644 --- a/v3/pkg/w32/user32.go +++ b/v3/pkg/w32/user32.go @@ -41,6 +41,7 @@ var ( procGetWindowText = moduser32.NewProc("GetWindowTextW") procGetWindowRect = moduser32.NewProc("GetWindowRect") procGetWindowInfo = moduser32.NewProc("GetWindowInfo") + procGetWindow = moduser32.NewProc("GetWindow") procSetWindowCompositionAttribute = moduser32.NewProc("SetWindowCompositionAttribute") procMoveWindow = moduser32.NewProc("MoveWindow") procScreenToClient = moduser32.NewProc("ScreenToClient") @@ -415,6 +416,14 @@ func GetWindowInfo(hwnd HWND, info *WINDOWINFO) int { return int(ret) } +func GetWindow(hwnd HWND, cmd uint32) HWND { + ret, _, _ := procGetWindow.Call( + hwnd, + uintptr(cmd), + ) + return HWND(ret) +} + func GetWindowText(hwnd HWND) string { textLen := GetWindowTextLength(hwnd) + 1