diff --git a/v3/STATUS.md b/v3/STATUS.md index 148c217b8..e84e0e58a 100644 --- a/v3/STATUS.md +++ b/v3/STATUS.md @@ -8,19 +8,19 @@ Application interface methods | Method | Windows | Linux | Mac | Notes | |---------------------------------------------------------------|---------|-------|-----|-------| -| run() error | | | ✅ | | -| destroy() | | | ✅ | | -| setApplicationMenu(menu *Menu) | | | ✅ | | -| name() string | | | ✅ | | -| getCurrentWindowID() uint | | | ✅ | | -| showAboutDialog(name string, description string, icon []byte) | | | ✅ | | -| setIcon(icon []byte) | | | ✅ | | -| on(id uint) | | | ✅ | | -| dispatchOnMainThread(id uint) | | | ✅ | | -| hide() | | | ✅ | | -| show() | | | ✅ | | -| getPrimaryScreen() (*Screen, error) | | | ✅ | | -| getScreens() ([]*Screen, error) | | | ✅ | | +| run() error | | | Y | | +| destroy() | | | Y | | +| setApplicationMenu(menu *Menu) | | | Y | | +| name() string | | | Y | | +| getCurrentWindowID() uint | | | Y | | +| showAboutDialog(name string, description string, icon []byte) | | | Y | | +| setIcon(icon []byte) | | | Y | | +| on(id uint) | | | Y | | +| dispatchOnMainThread(fn func()) | Y | | Y | | +| hide() | | | Y | | +| show() | | | Y | | +| getPrimaryScreen() (*Screen, error) | | | Y | | +| getScreens() ([]*Screen, error) | | | Y | | ## Webview Window @@ -28,52 +28,53 @@ Webview Window Interface Methods | Method | Windows | Linux | Mac | Notes | |----------------------------------------------------|---------|-------|-----|-------| -| setTitle(title string) | | | ✅ | | -| setSize(width, height int) | | | ✅ | | -| setAlwaysOnTop(alwaysOnTop bool) | | | ✅ | | -| setURL(url string) | | | ✅ | | -| setResizable(resizable bool) | | | ✅ | | -| setMinSize(width, height int) | | | ✅ | | -| setMaxSize(width, height int) | | | ✅ | | -| execJS(js string) | | | ✅ | | -| restore() | | | ✅ | | -| setBackgroundColour(color *RGBA) | | | ✅ | | -| run() | | | ✅ | | -| center() | | | ✅ | | -| size() (int, int) | | | ✅ | | -| width() int | | | ✅ | | -| height() int | | | ✅ | | -| position() (int, int) | | | ✅ | | -| destroy() | | | ✅ | | -| reload() | | | ✅ | | -| forceReload() | | | ✅ | | -| toggleDevTools() | | | ✅ | | -| zoomReset() | | | ✅ | | -| zoomIn() | | | ✅ | | -| zoomOut() | | | ✅ | | -| getZoom() float64 | | | ✅ | | -| setZoom(zoom float64) | | | ✅ | | -| close() | | | ✅ | | -| zoom() | | | ✅ | | -| setHTML(html string) | | | ✅ | | -| setPosition(x int, y int) | | | ✅ | | -| on(eventID uint) | | | ✅ | | -| minimise() | | | ✅ | | -| unminimise() | | | ✅ | | -| maximise() | | | ✅ | | -| unmaximise() | | | ✅ | | -| fullscreen() | | | ✅ | | -| unfullscreen() | | | ✅ | | -| isMinimised() bool | | | ✅ | | -| isMaximised() bool | | | ✅ | | -| isFullscreen() bool | | | ✅ | | -| disableSizeConstraints() | | | ✅ | | -| setFullscreenButtonEnabled(enabled bool) | | | ✅ | | -| show() | | | ✅ | | -| hide() | | | ✅ | | -| getScreen() (*Screen, error) | | | ✅ | | -| setFrameless(bool) | | | ✅ | | -| openContextMenu(menu *Menu, data *ContextMenuData) | | | ✅ | | +| setTitle(title string) | Y | | Y | | +| setSize(width, height int) | Y | | Y | | +| setAlwaysOnTop(alwaysOnTop bool) | Y | | Y | | +| setURL(url string) | | | Y | | +| setResizable(resizable bool) | Y | | Y | | +| setMinSize(width, height int) | | | Y | | +| setMaxSize(width, height int) | | | Y | | +| execJS(js string) | | | Y | | +| restore() | | | Y | | +| setBackgroundColour(color RGBA) | Y | | Y | | +| run() | Y | | Y | | +| center() | Y | | Y | | +| size() (int, int) | | | Y | | +| width() int | Y | | Y | | +| height() int | Y | | Y | | +| position() (int, int) | Y | | Y | | +| destroy() | | | Y | | +| reload() | | | Y | | +| forceReload() | | | Y | | +| toggleDevTools() | | | Y | | +| zoomReset() | | | Y | | +| zoomIn() | | | Y | | +| zoomOut() | | | Y | | +| getZoom() float64 | | | Y | | +| setZoom(zoom float64) | | | Y | | +| close() | | | Y | | +| zoom() | | | Y | | +| setHTML(html string) | | | Y | | +| setPosition(x int, y int) | | | Y | | +| on(eventID uint) | | | Y | | +| minimise() | Y | | Y | | +| unminimise() | Y | | Y | | +| maximise() | Y | | Y | | +| unmaximise() | Y | | Y | | +| fullscreen() | | | Y | | +| unfullscreen() | | | Y | | +| isMinimised() bool | Y | | Y | | +| isMaximised() bool | Y | | Y | | +| isFullscreen() bool | | | Y | | +| disableSizeConstraints() | | | Y | | +| setFullscreenButtonEnabled(enabled bool) | | | Y | | +| show() | Y | | Y | | +| hide() | Y | | Y | | +| getScreen() (*Screen, error) | | | Y | | +| setFrameless(bool) | | | Y | | +| openContextMenu(menu *Menu, data *ContextMenuData) | | | Y | | +| nativeWindowHandle() (uintptr, error) | Y | | | | ## Runtime @@ -81,73 +82,73 @@ Webview Window Interface Methods | Feature | Windows | Linux | Mac | Notes | |---------|---------|-------|-----|-------| -| Quit | | | ✅ | | -| Hide | | | ✅ | | -| Show | | | ✅ | | +| Quit | | | Y | | +| Hide | | | Y | | +| Show | | | Y | | ### Dialogs | Feature | Windows | Linux | Mac | Notes | |----------|---------|-------|-----|-------| -| Info | | | ✅ | | -| Warning | | | ✅ | | -| Error | | | ✅ | | -| Question | | | ✅ | | -| OpenFile | | | ✅ | | -| SaveFile | | | ✅ | | +| Info | | | Y | | +| Warning | | | Y | | +| Error | | | Y | | +| Question | | | Y | | +| OpenFile | | | Y | | +| SaveFile | | | Y | | ### Clipboard | Feature | Windows | Linux | Mac | Notes | |---------|---------|-------|-----|-------| -| SetText | | | ✅ | | -| Text | | | ✅ | | +| SetText | | | Y | | +| Text | | | Y | | ### ContextMenu | Feature | Windows | Linux | Mac | Notes | |-----------------|---------|-------|-----|-------| -| OpenContextMenu | | | ✅ | | +| OpenContextMenu | | | Y | | ### Screens | Feature | Windows | Linux | Mac | Notes | |------------|---------|-------|-----|-------| -| GetAll | | | ✅ | | -| GetPrimary | | | ✅ | | -| GetCurrent | | | ✅ | | +| GetAll | | | Y | | +| GetPrimary | | | Y | | +| GetCurrent | | | Y | | ### Window | Feature | Windows | Linux | Mac | Notes | |---------------------|---------|-------|-----|--------------------------------------------------------------------------------------| -| SetTitle | | | ✅ | | -| SetSize | | | ✅ | | -| Size | | | ✅ | | -| SetPosition | | | ✅ | | -| Position | | | ✅ | | -| FullScreen | | | ✅ | | -| UnFullscreen | | | ✅ | | -| Minimise | | | ✅ | | -| UnMinimise | | | ✅ | | -| Maximise | | | ✅ | | -| UnMaximise | | | ✅ | | -| Show | | | ✅ | | -| Hide | | | ✅ | | -| Center | | | ✅ | | -| SetBackgroundColour | | | ✅ | https://github.com/MicrosoftEdge/WebView2Feedback/issues/1621#issuecomment-938234294 | -| SetAlwaysOnTop | | | ✅ | | -| SetResizable | | | ✅ | | -| SetMinSize | | | ✅ | | -| SetMaxSize | | | ✅ | | -| Width | | | ✅ | | -| Height | | | ✅ | | -| ZoomIn | | | ✅ | Increase view scale | -| ZoomOut | | | ✅ | Decrease view scale | -| ZoomReset | | | ✅ | Reset view scale | -| GetZoom | | | ✅ | Get current view scale | -| SetZoom | | | ✅ | Set view scale | -| Screen | | | ✅ | Get screen for window | +| SetTitle | | | Y | | +| SetSize | | | Y | | +| Size | | | Y | | +| SetPosition | | | Y | | +| Position | | | Y | | +| FullScreen | | | Y | | +| UnFullscreen | | | Y | | +| Minimise | | | Y | | +| UnMinimise | | | Y | | +| Maximise | | | Y | | +| UnMaximise | | | Y | | +| Show | | | Y | | +| Hide | | | Y | | +| Center | | | Y | | +| SetBackgroundColour | | | Y | https://github.com/MicrosoftEdge/WebView2Feedback/issues/1621#issuecomment-938234294 | +| SetAlwaysOnTop | | | Y | | +| SetResizable | | | Y | | +| SetMinSize | | | Y | | +| SetMaxSize | | | Y | | +| Width | | | Y | | +| Height | | | Y | | +| ZoomIn | | | Y | Increase view scale | +| ZoomOut | | | Y | Decrease view scale | +| ZoomReset | | | Y | Reset view scale | +| GetZoom | | | Y | Get current view scale | +| SetZoom | | | Y | Set view scale | +| Screen | | | Y | Get screen for window | ### Log @@ -157,16 +158,16 @@ To log or not to log? System logger vs custom logger. | Event | Windows | Linux | Mac | Notes | |--------------------------|---------|-------|-----|-------| -| Default Application Menu | | | ✅ | | +| Default Application Menu | | | Y | | ## Tray Menus | Feature | Windows | Linux | Mac | Notes | |--------------------|---------|-------|-----|-------| -| Icon | | | ✅ | | -| Label | | | ✅ | | +| Icon | | | Y | | +| Label | | | Y | | | Label (ANSI Codes) | | | | | -| Menu | | | ✅ | | +| Menu | | | Y | | ## Cross Platform Events @@ -196,11 +197,11 @@ TBD ## Theme -| Plugin | Windows | Linux | Mac | Notes | -|-----------------|---------|-------|-----|-------| -| Dark | | | | | -| Light | | | | | -| System | | | | | +| Plugin | Windows | Linux | Mac | Notes | +|--------|---------|-------|-----|-------| +| Dark | Y | | | | +| Light | Y | | | | +| System | Y | | | | ## NSIS Installer @@ -216,31 +217,31 @@ Built-in plugin support: | Plugin | Windows | Linux | Mac | Notes | |-----------------|---------|-------|-----|-------| -| Browser | | | ✅ | | -| KV Store | | | ✅ | | -| Log | | | ✅ | | -| Single Instance | | | ✅ | | -| SQLite | | | ✅ | | -| Start at login | | | ✅ | | +| Browser | | | Y | | +| KV Store | | | Y | | +| Log | | | Y | | +| Single Instance | | | Y | | +| SQLite | | | Y | | +| Start at login | | | Y | | | Server | | | | | ## Packaging | | Windows | Linux | Mac | Notes | |-----------------|---------|-------|-----|-------| -| Icon Generation | | | ✅ | | -| Icon Embedding | | | ✅ | | -| Info.plist | | | ✅ | | +| Icon Generation | | | Y | | +| Icon Embedding | | | Y | | +| Info.plist | | | Y | | | NSIS Installer | | | | | -| Mac bundle | | | ✅ | | +| Mac bundle | | | Y | | | Windows exe | | | | | ## Frameless Windows | Feature | Windows | Linux | Mac | Notes | -|---------|---------|-------|----|-------| -| Resize | | | | | -| Drag | | | | | +|---------|---------|-------|-----|-------| +| Resize | | | | | +| Drag | | | | | ## Mac Specific @@ -248,4 +249,7 @@ Built-in plugin support: ## Windows Specific +- [x] Translucency +- [x] Custom Themes + ## Linux Specific diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 3b22e111d..638613b2d 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -22,7 +22,6 @@ type ( setMinSize(width, height int) setMaxSize(width, height int) execJS(js string) - restore() setBackgroundColour(color RGBA) run() center() @@ -53,6 +52,7 @@ type ( isMinimised() bool isMaximised() bool isFullscreen() bool + isNormal() bool disableSizeConstraints() setFullscreenButtonEnabled(enabled bool) show() @@ -102,6 +102,7 @@ func (w *WebviewWindow) onApplicationEvent(eventType events.ApplicationEventType w.addCancellationFunction(cancelFn) } +// NewWindow creates a new window with the given options func NewWindow(options *WebviewWindowOptions) *WebviewWindow { if options.Width == 0 { options.Width = 800 @@ -129,6 +130,7 @@ func (w *WebviewWindow) addCancellationFunction(canceller func()) { w.cancellers = append(w.cancellers, canceller) } +// SetTitle sets the title of the window func (w *WebviewWindow) SetTitle(title string) *WebviewWindow { w.implLock.RLock() defer w.implLock.RUnlock() @@ -139,10 +141,12 @@ func (w *WebviewWindow) SetTitle(title string) *WebviewWindow { return w } +// Name returns the name of the window func (w *WebviewWindow) Name() string { return w.options.Name } +// SetSize sets the size of the window func (w *WebviewWindow) SetSize(width, height int) *WebviewWindow { // Don't set size if fullscreen if w.IsFullscreen() { @@ -193,6 +197,7 @@ func (w *WebviewWindow) run() { w.impl.run() } +// SetAlwaysOnTop sets the window to be always on top. func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { w.options.AlwaysOnTop = b if w.impl != nil { @@ -201,6 +206,7 @@ func (w *WebviewWindow) SetAlwaysOnTop(b bool) *WebviewWindow { return w } +// Show shows the window. func (w *WebviewWindow) Show() *WebviewWindow { if globalApplication.impl == nil { return w @@ -212,6 +218,8 @@ func (w *WebviewWindow) Show() *WebviewWindow { w.impl.show() return w } + +// Hide hides the window. func (w *WebviewWindow) Hide() *WebviewWindow { w.options.Hidden = true if w.impl != nil { @@ -228,6 +236,7 @@ func (w *WebviewWindow) SetURL(s string) *WebviewWindow { return w } +// SetZoom sets the zoom level of the window. func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow { w.options.Zoom = magnification if w.impl != nil { @@ -236,6 +245,7 @@ func (w *WebviewWindow) SetZoom(magnification float64) *WebviewWindow { return w } +// GetZoom returns the current zoom level of the window. func (w *WebviewWindow) GetZoom() float64 { if w.impl != nil { return w.impl.getZoom() @@ -243,6 +253,7 @@ func (w *WebviewWindow) GetZoom() float64 { return 1 } +// SetResizable sets whether the window is resizable. func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow { w.options.DisableResize = !b if w.impl != nil { @@ -251,10 +262,12 @@ func (w *WebviewWindow) SetResizable(b bool) *WebviewWindow { return w } +// Resizable returns true if the window is resizable. func (w *WebviewWindow) Resizable() bool { return !w.options.DisableResize } +// SetMinSize sets the minimum size of the window. func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) *WebviewWindow { w.options.MinWidth = minWidth w.options.MinHeight = minHeight @@ -282,6 +295,7 @@ func (w *WebviewWindow) SetMinSize(minWidth, minHeight int) *WebviewWindow { return w } +// SetMaxSize sets the maximum size of the window. func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) *WebviewWindow { w.options.MaxWidth = maxWidth w.options.MaxHeight = maxHeight @@ -309,6 +323,7 @@ func (w *WebviewWindow) SetMaxSize(maxWidth, maxHeight int) *WebviewWindow { return w } +// ExecJS executes the given javascript in the context of the window. func (w *WebviewWindow) ExecJS(js string) { if w.impl == nil { return @@ -316,6 +331,7 @@ func (w *WebviewWindow) ExecJS(js string) { w.impl.execJS(js) } +// Fullscreen sets the window to fullscreen mode. Min/Max size constraints are disabled. func (w *WebviewWindow) Fullscreen() *WebviewWindow { if w.impl == nil { w.options.StartState = WindowStateFullscreen @@ -370,6 +386,7 @@ func (w *WebviewWindow) IsFullscreen() bool { return w.impl.isFullscreen() } +// SetBackgroundColour sets the background colour of the window func (w *WebviewWindow) SetBackgroundColour(colour RGBA) *WebviewWindow { w.options.BackgroundColour = colour if w.impl != nil { @@ -388,6 +405,7 @@ func (w *WebviewWindow) handleMessage(message string) { } +// Center centers the window on the screen func (w *WebviewWindow) Center() { if w.impl == nil { return @@ -395,6 +413,7 @@ func (w *WebviewWindow) Center() { w.impl.center() } +// On registers a callback for the given window event func (w *WebviewWindow) On(eventType events.WindowEventType, callback func(ctx *WindowEventContext)) func() { eventID := uint(eventType) w.eventListenersLock.Lock() @@ -423,6 +442,7 @@ func (w *WebviewWindow) handleWindowEvent(id uint) { w.eventListenersLock.RUnlock() } +// Width returns the width of the window func (w *WebviewWindow) Width() int { if w.impl == nil { return 0 @@ -430,6 +450,7 @@ func (w *WebviewWindow) Width() int { return w.impl.width() } +// Height returns the height of the window func (w *WebviewWindow) Height() int { if w.impl == nil { return 0 @@ -437,6 +458,7 @@ func (w *WebviewWindow) Height() int { return w.impl.height() } +// Position returns the position of the window func (w *WebviewWindow) Position() (int, int) { w.implLock.RLock() defer w.implLock.RUnlock() @@ -457,6 +479,7 @@ func (w *WebviewWindow) Destroy() { w.impl.destroy() } +// Reload reloads the page assets func (w *WebviewWindow) Reload() { if w.impl == nil { return @@ -464,6 +487,7 @@ func (w *WebviewWindow) Reload() { w.impl.reload() } +// ForceReload forces the window to reload the page assets func (w *WebviewWindow) ForceReload() { if w.impl == nil { return @@ -471,6 +495,7 @@ func (w *WebviewWindow) ForceReload() { w.impl.forceReload() } +// ToggleFullscreen toggles the window between fullscreen and normal func (w *WebviewWindow) ToggleFullscreen() { if w.impl == nil { return @@ -489,6 +514,7 @@ func (w *WebviewWindow) ToggleDevTools() { w.impl.toggleDevTools() } +// ZoomReset resets the zoom level of the webview content to 100% func (w *WebviewWindow) ZoomReset() *WebviewWindow { if w.impl != nil { w.impl.zoomReset() @@ -497,6 +523,7 @@ func (w *WebviewWindow) ZoomReset() *WebviewWindow { } +// ZoomIn increases the zoom level of the webview content func (w *WebviewWindow) ZoomIn() { if w.impl == nil { return @@ -504,6 +531,7 @@ func (w *WebviewWindow) ZoomIn() { w.impl.zoomIn() } +// ZoomOut decreases the zoom level of the webview content func (w *WebviewWindow) ZoomOut() { if w.impl == nil { return @@ -511,6 +539,7 @@ func (w *WebviewWindow) ZoomOut() { w.impl.zoomOut() } +// Close closes the window func (w *WebviewWindow) Close() { if w.impl == nil { return @@ -518,13 +547,6 @@ func (w *WebviewWindow) Close() { w.impl.close() } -func (w *WebviewWindow) Minimize() { - if w.impl == nil { - return - } - w.impl.minimise() -} - func (w *WebviewWindow) Zoom() { if w.impl == nil { return @@ -532,6 +554,7 @@ func (w *WebviewWindow) Zoom() { w.impl.zoom() } +// SetHTML sets the HTML of the window to the given html string. func (w *WebviewWindow) SetHTML(html string) *WebviewWindow { w.options.HTML = html if w.impl != nil { @@ -540,6 +563,7 @@ func (w *WebviewWindow) SetHTML(html string) *WebviewWindow { return w } +// SetPosition sets the position of the window. func (w *WebviewWindow) SetPosition(x, y int) *WebviewWindow { w.options.X = x w.options.Y = y @@ -549,6 +573,7 @@ func (w *WebviewWindow) SetPosition(x, y int) *WebviewWindow { return w } +// Minimise minimises the window. func (w *WebviewWindow) Minimise() *WebviewWindow { if w.impl == nil { w.options.StartState = WindowStateMinimised @@ -560,6 +585,7 @@ func (w *WebviewWindow) Minimise() *WebviewWindow { return w } +// Maximise maximises the window. Min/Max size constraints are disabled. func (w *WebviewWindow) Maximise() *WebviewWindow { if w.impl == nil { w.options.StartState = WindowStateMaximised @@ -572,29 +598,39 @@ func (w *WebviewWindow) Maximise() *WebviewWindow { return w } +// UnMinimise un-minimises the window. Min/Max size constraints are re-enabled. func (w *WebviewWindow) UnMinimise() { if w.impl == nil { return } - w.impl.unminimise() + if w.IsMinimised() { + w.impl.unminimise() + } } +// UnMaximise un-maximises the window. func (w *WebviewWindow) UnMaximise() { if w.impl == nil { return } - w.enableSizeConstraints() - w.impl.unmaximise() + if w.IsMaximised() { + w.enableSizeConstraints() + w.impl.unmaximise() + } } +// UnFullscreen un-fullscreens the window. func (w *WebviewWindow) UnFullscreen() { if w.impl == nil { return } - w.enableSizeConstraints() - w.impl.unfullscreen() + if w.IsFullscreen() { + w.enableSizeConstraints() + w.impl.unfullscreen() + } } +// Restore restores the window to its previous state if it was previously minimised, maximised or fullscreen. func (w *WebviewWindow) Restore() { if w.impl == nil { return @@ -612,18 +648,27 @@ func (w *WebviewWindow) disableSizeConstraints() { if w.impl == nil { return } - w.impl.setMinSize(0, 0) - w.impl.setMaxSize(0, 0) + if w.options.MinWidth > 0 && w.options.MinHeight > 0 { + w.impl.setMinSize(0, 0) + } + if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { + w.impl.setMaxSize(0, 0) + } } func (w *WebviewWindow) enableSizeConstraints() { if w.impl == nil { return } - w.SetMinSize(w.options.MinWidth, w.options.MinHeight) - w.SetMaxSize(w.options.MaxWidth, w.options.MaxHeight) + if w.options.MinWidth > 0 && w.options.MinHeight > 0 { + w.SetMinSize(w.options.MinWidth, w.options.MinHeight) + } + if w.options.MaxWidth > 0 && w.options.MaxHeight > 0 { + w.SetMaxSize(w.options.MaxWidth, w.options.MaxHeight) + } } +// GetScreen returns the screen that the window is on func (w *WebviewWindow) GetScreen() (*Screen, error) { if w.impl == nil { return nil, nil @@ -631,6 +676,7 @@ func (w *WebviewWindow) GetScreen() (*Screen, error) { return w.impl.getScreen() } +// SetFrameless removes the window frame and title bar func (w *WebviewWindow) SetFrameless(frameless bool) *WebviewWindow { w.options.Frameless = frameless if w.impl != nil { @@ -690,12 +736,14 @@ func (w *WebviewWindow) openContextMenu(data *ContextMenuData) { w.impl.openContextMenu(menu, data) } +// RegisterContextMenu registers a context menu and assigns it the given name. func (w *WebviewWindow) RegisterContextMenu(name string, menu *Menu) { w.contextMenusLock.Lock() defer w.contextMenusLock.Unlock() w.contextMenus[name] = menu } +// NativeWindowHandle returns the platform native window handle for the window. func (w *WebviewWindow) NativeWindowHandle() (uintptr, error) { if w.impl == nil { return 0, errors.New("native handle unavailable as window is not running") diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 2a471eb3f..f86bbdd06 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -26,12 +26,12 @@ func (w *windowsWebviewWindow) nativeWindowHandle() uintptr { } func (w *windowsWebviewWindow) setTitle(title string) { - //TODO implement me - panic("implement me") + w32.SetWindowText(w.hwnd, title) } func (w *windowsWebviewWindow) setSize(width, height int) { x, y := w.position() + // TODO: Take scaling/DPI into consideration w32.MoveWindow(w.hwnd, x, y, width, height, true) } @@ -71,11 +71,6 @@ func (w *windowsWebviewWindow) execJS(js string) { panic("implement me") } -func (w *windowsWebviewWindow) restore() { - //TODO implement me - panic("implement me") -} - func (w *windowsWebviewWindow) setBackgroundColour(color RGBA) { w32.SetBackgroundColour(w.hwnd, color.Red, color.Green, color.Blue) } @@ -161,8 +156,7 @@ func (w *windowsWebviewWindow) _run() { } func (w *windowsWebviewWindow) center() { - //TODO implement me - panic("implement me") + w32.CenterWindow(w.hwnd) } func (w *windowsWebviewWindow) size() (int, int) { @@ -264,23 +258,29 @@ func (w *windowsWebviewWindow) on(eventID uint) { } func (w *windowsWebviewWindow) minimise() { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_MINIMIZE) + }) } func (w *windowsWebviewWindow) unminimise() { - //TODO implement me - panic("implement me") + w.restore() } func (w *windowsWebviewWindow) maximise() { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_MAXIMIZE) + }) } func (w *windowsWebviewWindow) unmaximise() { - //TODO implement me - panic("implement me") + w.restore() +} + +func (w *windowsWebviewWindow) restore() { + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_RESTORE) + }) } func (w *windowsWebviewWindow) fullscreen() { @@ -294,13 +294,13 @@ func (w *windowsWebviewWindow) unfullscreen() { } func (w *windowsWebviewWindow) isMinimised() bool { - //TODO implement me - panic("implement me") + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_MINIMIZE != 0 } func (w *windowsWebviewWindow) isMaximised() bool { - //TODO implement me - panic("implement me") + style := uint32(w32.GetWindowLong(w.hwnd, w32.GWL_STYLE)) + return style&w32.WS_MAXIMIZE != 0 } func (w *windowsWebviewWindow) isFullscreen() bool { @@ -308,6 +308,10 @@ func (w *windowsWebviewWindow) isFullscreen() bool { panic("implement me") } +func (w *windowsWebviewWindow) isNormal() bool { + return !w.isMinimised() && !w.isMaximised() && !w.isFullscreen() +} + func (w *windowsWebviewWindow) disableSizeConstraints() { //TODO implement me panic("implement me") @@ -319,12 +323,15 @@ func (w *windowsWebviewWindow) setFullscreenButtonEnabled(enabled bool) { } func (w *windowsWebviewWindow) show() { - w32.ShowWindow(w.hwnd, w32.SW_SHOW) + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_SHOW) + }) } func (w *windowsWebviewWindow) hide() { - //TODO implement me - panic("implement me") + globalApplication.dispatchOnMainThread(func() { + w32.ShowWindow(w.hwnd, w32.SW_HIDE) + }) } func (w *windowsWebviewWindow) getScreen() (*Screen, error) { @@ -404,7 +411,6 @@ func (w *windowsWebviewWindow) setIcon(icon w32.HICON) { func (w *windowsWebviewWindow) disableIcon() { // TODO: If frameless, return - exStyle := w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE) w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, uint32(exStyle|w32.WS_EX_DLGMODALFRAME)) w32.SetWindowPos(w.hwnd, 0, 0, 0, 0, 0, diff --git a/v3/pkg/w32/window.go b/v3/pkg/w32/window.go index 67e20f017..22cdb0411 100644 --- a/v3/pkg/w32/window.go +++ b/v3/pkg/w32/window.go @@ -135,3 +135,39 @@ func MustUTF16FromString(input string) []uint16 { } return ret } + +func CenterWindow(hwnd HWND) { + windowInfo := getWindowInfo(hwnd) + frameless := windowInfo.IsPopup() + + info := getMonitorInfo(hwnd) + workRect := info.RcWork + screenMiddleW := workRect.Left + (workRect.Right-workRect.Left)/2 + screenMiddleH := workRect.Top + (workRect.Bottom-workRect.Top)/2 + var winRect *RECT + if !frameless { + winRect = GetWindowRect(hwnd) + } else { + winRect = GetClientRect(hwnd) + } + winWidth := winRect.Right - winRect.Left + winHeight := winRect.Bottom - winRect.Top + windowX := screenMiddleW - (winWidth / 2) + windowY := screenMiddleH - (winHeight / 2) + SetWindowPos(hwnd, HWND_TOP, int(windowX), int(windowY), int(winWidth), int(winHeight), SWP_NOSIZE) +} + +func getWindowInfo(hwnd HWND) *WINDOWINFO { + var info WINDOWINFO + info.CbSize = uint32(unsafe.Sizeof(info)) + GetWindowInfo(hwnd, &info) + return &info +} + +func getMonitorInfo(hwnd HWND) *MONITORINFO { + currentMonitor := MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) + var info MONITORINFO + info.CbSize = uint32(unsafe.Sizeof(info)) + GetMonitorInfo(currentMonitor, &info) + return &info +}