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

Add automatic focusing of the WebView2 widget. #38

Merged
merged 2 commits into from
Feb 13, 2022
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: 2 additions & 1 deletion cmd/demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (

func main() {
w := webview2.NewWithOptions(webview2.WebViewOptions{
Debug: true,
Debug: true,
AutoFocus: true,
WindowOptions: webview2.WindowOptions{
Title: "Minimal webview example",
},
Expand Down
7 changes: 7 additions & 0 deletions internal/w32/w32.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const (
WMDestroy = 0x0002
WMMove = 0x0003
WMSize = 0x0005
WMActivate = 0x0006
WMClose = 0x0010
WMQuit = 0x0012
WMGetMinMaxInfo = 0x0024
Expand Down Expand Up @@ -91,6 +92,12 @@ const (
WSOverlappedWindow = (WSOverlapped | WSCaption | WSSysMenu | WSThickFrame | WSMinimizeBox | WSMaximizeBox)
)

const (
WAInactive = 0
WAActive = 1
WAActiveClick = 2
)

type WndClassExW struct {
CbSize uint32
Style uint32
Expand Down
9 changes: 9 additions & 0 deletions pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package edge

type COREWEBVIEW2_MOVE_FOCUS_REASON uint32

const (
COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC = 0
COREWEBVIEW2_MOVE_FOCUS_REASON_NEXT = 1
COREWEBVIEW2_MOVE_FOCUS_REASON_PREVIOUS = 2
)
12 changes: 12 additions & 0 deletions pkg/edge/ICoreWebView2Controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,15 @@ func (i *ICoreWebView2Controller) NotifyParentWindowPositionChanged() error {
}
return nil
}

func (i *ICoreWebView2Controller) MoveFocus(reason uintptr) error {
var err error
_, _, err = i.vtbl.MoveFocus.Call(
uintptr(unsafe.Pointer(i)),
uintptr(reason),
)
if err != windows.ERROR_SUCCESS {
return err
}
return nil
}
13 changes: 13 additions & 0 deletions pkg/edge/chromium.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (

type Chromium struct {
hwnd uintptr
focusOnInit bool
controller *ICoreWebView2Controller
webview *ICoreWebView2
inited uintptr
Expand Down Expand Up @@ -216,6 +217,10 @@ func (e *Chromium) CreateCoreWebView2ControllerCompleted(res uintptr, controller

atomic.StoreUintptr(&e.inited, 1)

if e.focusOnInit {
e.Focus()
}

return 0
}

Expand Down Expand Up @@ -340,3 +345,11 @@ func (e *Chromium) NotifyParentWindowPositionChanged() error {
}
return e.controller.NotifyParentWindowPositionChanged()
}

func (e *Chromium) Focus() {
if e.controller == nil {
e.focusOnInit = true
return
}
_ = e.controller.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
}
23 changes: 21 additions & 2 deletions webview.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ type browser interface {
Init(script string)
Eval(script string)
NotifyParentWindowPositionChanged() error
Focus()
}

type webview struct {
hwnd uintptr
mainthread uintptr
browser browser
autofocus bool
maxsz w32.Point
minsz w32.Point
m sync.Mutex
Expand All @@ -60,10 +62,19 @@ type WindowOptions struct {
}

type WebViewOptions struct {
Window unsafe.Pointer
Debug bool
Window unsafe.Pointer
Debug bool

// DataPath specifies the datapath for the WebView2 runtime to use for the
// browser instance.
DataPath string

// AutoFocus will try to keep the WebView2 widget focused when the window
// is focused.
AutoFocus bool

// WindowOptions customizes the window that is created to embed the
// WebView2 widget.
WindowOptions WindowOptions
}

Expand All @@ -81,6 +92,7 @@ func NewWindow(debug bool, window unsafe.Pointer) WebView {
func NewWithOptions(options WebViewOptions) WebView {
w := &webview{}
w.bindings = map[string]interface{}{}
w.autofocus = options.AutoFocus

chromium := edge.NewChromium()
chromium.MessageCallback = w.msgcb
Expand Down Expand Up @@ -198,6 +210,13 @@ func wndproc(hwnd, msg, wp, lp uintptr) uintptr {
return r
case w32.WMSize:
w.browser.Resize()
case w32.WMActivate:
if wp == w32.WAInactive {
break
}
if w.autofocus {
w.browser.Focus()
}
case w32.WMClose:
_, _, _ = w32.User32DestroyWindow.Call(hwnd)
case w32.WMDestroy:
Expand Down