Skip to content

Commit

Permalink
move to NativeWindow interface, implement for other platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
dweymouth committed May 21, 2024
1 parent 758026f commit 7b8939c
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 37 deletions.
11 changes: 0 additions & 11 deletions driver/desktop/window.go

This file was deleted.

28 changes: 23 additions & 5 deletions driver/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,34 @@ type AndroidContext struct {
}

// UnknownContext is passed to the RunNative callback when it is executed
// on devices without special native context.
// on devices or windows without special native context.
//
// Since: 2.3
type UnknownContext struct{}

// WindowsContext is passed to the `(desktop.Window).RunNative` callback
// when it is executed on a Microsoft Windows desktop device.
// WindowsWindowContext is passed to the `(fyne.NativeWindow).RunNative` callback
// when it is executed on a Microsoft Windows device.
//
// Since: 2.5
type WindowsContext struct {
// HWND is the WinAPI HWND for the window.
type WindowsWindowContext struct {
// HWND is the window handle for the native window.
HWND uintptr
}

// MacWindowContext is passed to the `(fyne.NativeWindow).RunNative` callback
// when it is executed on a Mac OS device.
//
// Since: 2.5
type MacWindowContext struct {
// NSWindow is the window handle for the native window.
NSWindow uintptr
}

// X11WindowContext is passed to the `(fyne.NativeWindow).RunNative` callback
// when it is executed on a device with the X11 windowing system.
//
// Since: 2.5
type X11WindowContext struct {
// WindowHandle is the window handle for the native X11 window.
WindowHandle string
}
24 changes: 24 additions & 0 deletions internal/driver/glfw/window_darwin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//go:build darwin

package glfw

import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
)

// assert we are implementing fyne.NativeWindow
var _ fyne.NativeWindow = (*window)(nil)

func (w *window) RunNative(f func(any) error) error {
var err error
done := make(chan struct{})
runOnMain(func() {
err = f(driver.MacWindowContext{
NSWindow: uintptr(w.view().GetCocoaWindow()),
})
close(done)
})
<-done
return err
}
16 changes: 0 additions & 16 deletions internal/driver/glfw/window_notwindows.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ package glfw

import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/internal/scale"
)

Expand All @@ -15,17 +13,3 @@ func (w *window) setDarkMode() {
func (w *window) computeCanvasSize(width, height int) fyne.Size {
return fyne.NewSize(scale.ToFyneCoordinate(w.canvas, width), scale.ToFyneCoordinate(w.canvas, height))
}

// assert we are implementing desktop.Window
var _ desktop.Window = (*window)(nil)

func (w *window) RunNative(f func(any) error) error {
var err error
done := make(chan struct{})
runOnMain(func() {
err = f(driver.UnknownContext{})
close(done)
})
<-done
return err
}
20 changes: 20 additions & 0 deletions internal/driver/glfw/window_wayland.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,27 @@

package glfw

import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
)

// GetWindowHandle returns the window handle. Only implemented for X11 currently.
func (w *window) GetWindowHandle() string {
return "" // TODO: Find a way to get the Wayland handle for xdg_foreign protocol. Return "wayland:{id}".
}

// assert we are implementing fyne.NativeWindow
var _ fyne.NativeWindow = (*window)(nil)

func (w *window) RunNative(f func(any) error) error {
var err error
done := make(chan struct{})
runOnMain(func() {
// TODO: define driver.WaylandWindowContext and pass window handle
err = f(driver.UnknownContext{})
close(done)
})
<-done
return err
}
7 changes: 3 additions & 4 deletions internal/driver/glfw/window_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/internal/scale"

"golang.org/x/sys/windows/registry"
Expand Down Expand Up @@ -53,14 +52,14 @@ func (w *window) computeCanvasSize(width, height int) fyne.Size {
return fyne.NewSize(scale.ToFyneCoordinate(w.canvas, width), scale.ToFyneCoordinate(w.canvas, height))
}

// assert we are implementing desktop.Window
var _ desktop.Window = (*window)(nil)
// assert we are implementing fyne.NativeWindow
var _ fyne.NativeWindow = (*window)(nil)

func (w *window) RunNative(f func(any) error) error {
var err error
done := make(chan struct{})
runOnMain(func() {
err = f(driver.WindowsContext{
err = f(driver.WindowsWindowContext{
HWND: uintptr(unsafe.Pointer(w.view().GetWin32Window())),
})
close(done)
Expand Down
23 changes: 22 additions & 1 deletion internal/driver/glfw/window_x11.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,31 @@

package glfw

import "strconv"
import (
"strconv"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
)

// GetWindowHandle returns the window handle. Only implemented for X11 currently.
func (w *window) GetWindowHandle() string {
xid := uint(w.viewport.GetX11Window())
return "x11:" + strconv.FormatUint(uint64(xid), 16)
}

// assert we are implementing fyne.NativeWindow
var _ fyne.NativeWindow = (*window)(nil)

func (w *window) RunNative(f func(any) error) error {
var err error
done := make(chan struct{})
runOnMain(func() {
err = f(driver.X11WindowContext{
WindowHandle: w.GetWindowHandle(),
})
close(done)
})
<-done
return err
}
20 changes: 20 additions & 0 deletions internal/driver/mobile/window_android.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build android

package mobile

import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
"fyne.io/fyne/v2/internal/driver/mobile/app"
)

// Assert we are satisfying the NativeWindow interface
var _ fyne.NativeWindow = (*window)(nil)

func (w *window) RunNative(f func(context any) error) error {
return app.RunOnJVM(func(vm, env, ctx uintptr) error {
// TODO: define driver.AndroidWindowContext that also includes the View
data := &driver.AndroidContext{VM: vm, Env: env, Ctx: ctx}
return f(data)
})
}
15 changes: 15 additions & 0 deletions internal/driver/mobile/window_ios.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//go:build ios

package mobile

import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/driver"
)

// Assert we are satisfying the NativeWindow interface
var _ fyne.NativeWindow = (*window)(nil)

func (w *window) RunNative(fn func(context any) error) error {
return fn(&driver.UnknownContext{})
}
10 changes: 10 additions & 0 deletions window.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,13 @@ type Window interface {
// Clipboard returns the system clipboard
Clipboard() Clipboard
}

// NativeWindow is an extension interface for Window that gives access
// to platform-native features of application windows.
//
// Since: 2.5
type NativeWindow interface {
// RunNative provides a way to execute code within the platform-specific runtime context for a window.
// The context types are defined in the `driver` package and the specific context passed will differ by platform.
RunNative(func(context any) error) error
}

0 comments on commit 7b8939c

Please sign in to comment.