Skip to content

Commit

Permalink
io,app: fix compatibility with gio 0.6
Browse files Browse the repository at this point in the history
Signed-off-by: inkeliz <[email protected]>
  • Loading branch information
inkeliz committed Jun 3, 2024
1 parent 8564fa9 commit ce5792f
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 50 deletions.
3 changes: 0 additions & 3 deletions app/internal/windows/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ package windows

import (
"fmt"
"golang.org/x/sys/windows/registry"
"os"
"path/filepath"
"runtime"
"time"
"unicode/utf16"
Expand Down
3 changes: 1 addition & 2 deletions app/os_android.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ import (
"gioui.org/io/pointer"
"gioui.org/io/semantic"
"gioui.org/io/system"
"gioui.org/io/transfer"
"gioui.org/unit"
)

Expand Down Expand Up @@ -676,7 +675,7 @@ func Java_org_gioui_GioView_onOpenURI(env *C.JNIEnv, class C.jclass, view C.jlon
if err != nil {
return
}
w.callbacks.Event(transfer.URLEvent{URL: u})
w.ProcessEvent(transfer.URLEvent{URL: u})
}

func (w *window) ProcessEvent(e event.Event) {
Expand Down
30 changes: 25 additions & 5 deletions app/os_ios.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import (
"runtime/cgo"
"runtime/debug"
"strings"
"sync"
"time"
"unicode/utf16"
"unsafe"
Expand Down Expand Up @@ -120,6 +121,16 @@ type window struct {

var mainWindow = newWindowRendezvous()

// activeViews is the list of active views.
var activeViews = make([]*window, 0, 1)

// mutexActiveViews is used to protect activeViews.
var mutexActiveViews = sync.Mutex{}

// startupURI is the URI to open when the first window is created,
// but no window is active yet.
var startupURI *url.URL

func init() {
// Darwin requires UI operations happen on the main thread only.
runtime.LockOSThread()
Expand All @@ -144,6 +155,9 @@ func onCreate(view, controller C.CFTypeRef) {
}
w.displayLink = dl
C.gio_viewSetHandle(view, C.uintptr_t(cgo.NewHandle(w)))
mutexActiveViews.Lock()
activeViews = append(activeViews, w)
mutexActiveViews.Unlock()
w.Configure(wopts.options)
w.ProcessEvent(UIKitViewEvent{ViewController: uintptr(controller)})
if startupURI != nil {
Expand Down Expand Up @@ -216,6 +230,14 @@ func onDestroy(h C.uintptr_t) {
w.displayLink.Close()
w.displayLink = nil
cgo.Handle(h).Delete()
mutexActiveViews.Lock()
for i, v := range activeViews {
if v == w {
activeViews = append(activeViews[:i], activeViews[i+1:]...)
break
}
}
mutexActiveViews.Unlock()
w.view = 0
}

Expand Down Expand Up @@ -402,20 +424,18 @@ func newWindow(win *callbacks, options []Option) {
func osMain() {
}

var startupURI *url.URL

//export gio_onOpenURI
func gio_onOpenURI(uri C.CFTypeRef) {
u, err := url.Parse(nsstringToString(uri))
if err != nil {
return
}
if len(views) == 0 {
if len(activeViews) == 0 {
startupURI = u
return
}
for _, w := range views {
w.w.Event(transfer.URLEvent{URL: u})
for _, w := range activeViews {
w.ProcessEvent(transfer.URLEvent{URL: u})
}
}

Expand Down
46 changes: 35 additions & 11 deletions app/os_macos.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ package app
import (
"errors"
"image"
"net/url"
"io"
"net/url"
"runtime"
"runtime/cgo"
"strings"
"sync"
"time"
"unicode"
"unicode/utf8"
Expand Down Expand Up @@ -336,6 +337,17 @@ type window struct {
// launched is closed when applicationDidFinishLaunching is called.
var launched = make(chan struct{})

// activeViews is the list of active windows.
var activeViews = make([]*window, 0, 1)

// mutexActiveViews protects activeViews.
var mutexActiveViews = sync.Mutex{}

// startupURI is the URL event that was received before the app was launched.
// Since the app is not running yet, the URL event is stored and processed after
// the view is created.
var startupURI *url.URL

// nextTopLeft is the offset to use for the next window's call to
// cascadeTopLeftFromPoint.
var nextTopLeft C.NSPoint
Expand Down Expand Up @@ -869,6 +881,10 @@ func gio_onAttached(h C.uintptr_t, attached C.int) {
if attached != 0 {
layer := C.layerForView(w.view)
w.ProcessEvent(AppKitViewEvent{View: uintptr(w.view), Layer: uintptr(layer)})
if startupURI != nil {
w.ProcessEvent(transfer.URLEvent{URL: startupURI})
startupURI = nil
}
} else {
w.ProcessEvent(AppKitViewEvent{})
w.visible = false
Expand All @@ -883,6 +899,14 @@ func gio_onDestroy(h C.uintptr_t) {
w.displayLink.Close()
w.displayLink = nil
cgo.Handle(h).Delete()
mutexActiveViews.Lock()
for i, win := range activeViews {
if win == w {
activeViews = append(activeViews[:i], activeViews[i+1:]...)
break
}
}
mutexActiveViews.Unlock()
w.view = 0
}

Expand Down Expand Up @@ -918,20 +942,21 @@ func gio_onFinishLaunching() {
close(launched)
}

var startupURI *url.URL

//export gio_onOpenURI
func gio_onOpenURI(h C.uintptr_t, uri C.CFTypeRef) {
func gio_onOpenURI(uri C.CFTypeRef) {
u, err := url.Parse(nsstringToString(uri))
if err != nil {
return
}
if len(viewMap) == 0 {

if len(activeViews) == 0 {
startupURI = u
return
}
w := windowFor(h)
w.ProcessEvent(transfer.URLEvent{URL: u})

for _, w := range activeViews {
w.ProcessEvent(transfer.URLEvent{URL: u})
}
}

func newWindow(win *callbacks, options []Option) {
Expand Down Expand Up @@ -963,10 +988,6 @@ func newWindow(win *callbacks, options []Option) {
C.makeKeyAndOrderFront(window)
w.initialized = true
res <- struct{}{}
if startupURI != nil {
w.ProcessEvent(transfer.URLEvent{URL: startupURI})
startupURI = nil
}
w.loop.FlushEvents()
})
<-res
Expand Down Expand Up @@ -997,6 +1018,9 @@ func (w *window) init() error {
return err
}
C.gio_viewSetHandle(view, C.uintptr_t(cgo.NewHandle(w)))
mutexActiveViews.Lock()
activeViews = append(activeViews, w)
mutexActiveViews.Unlock()
w.view = view
return nil
}
Expand Down
7 changes: 1 addition & 6 deletions app/os_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ CFTypeRef gio_createView(void) {
selector:@selector(applicationDidHide:)
name:NSApplicationDidHideNotification
object:nil];

return CFBridgingRetain(view);
}
}
Expand All @@ -412,12 +413,6 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[NSApp activateIgnoringOtherApps:YES];
gio_onFinishLaunching();
}
- (void)applicationDidHide:(NSNotification *)aNotification {
gio_onAppHide();
}
- (void)applicationWillUnhide:(NSNotification *)notification {
gio_onAppShow();
}
- (void)application:(NSApplication *)application openURLs:(NSArray<NSURL *> *)urls {
for (NSURL *url in urls) {
gio_onOpenURI((__bridge CFTypeRef)url.absoluteString);
Expand Down
37 changes: 16 additions & 21 deletions app/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
syscall "golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"image"
"io"
"net/url"
"os"
"io"
"runtime"
"sort"
"strings"
Expand All @@ -21,8 +21,6 @@ import (
"unicode/utf8"
"unsafe"

syscall "golang.org/x/sys/windows"

"gioui.org/app/internal/windows"
"gioui.org/op"
"gioui.org/unit"
Expand All @@ -33,7 +31,6 @@ import (
"gioui.org/io/key"
"gioui.org/io/pointer"
"gioui.org/io/system"
"gioui.org/io/transfer"
)

type Win32ViewEvent struct {
Expand Down Expand Up @@ -120,9 +117,8 @@ func newWindow(win *callbacks, options []Option) {
winMap.Store(w.hwnd, w)
defer winMap.Delete(w.hwnd)
w.ProcessEvent(Win32ViewEvent{HWND: uintptr(w.hwnd)})
if startupURI != "" {
w.onOpenURI(startupURI)
startupURI = ""
if u := startupURI(); u != "" {
w.onOpenURI(u)
}
w.Configure(options)
windows.SetForegroundWindow(w.hwnd)
Expand Down Expand Up @@ -1045,16 +1041,14 @@ func (Win32ViewEvent) ImplementsEvent() {}
// defined using -X compiler ldflag, that used in gogio.
var schemesURI string

// startupURI is the URI that started the app, if any.
var startupURI string

func init() {
var currentSchemes []string
if schemesURI != "" {
currentSchemes = strings.Split(schemesURI, ",")
if schemesURI == "" {
return
}

currentSchemes := strings.Split(schemesURI, ",")
oldSchemes := registeredSchemes(ID)

for _, s := range currentSchemes {
for i, o := range oldSchemes {
if s == o {
Expand All @@ -1072,16 +1066,12 @@ func init() {
return
}

if len(os.Args) == 3 && os.Args[1] == "-gio_launch_url" {
startupURI = os.Args[2]
}

// On Windows, launching the app using a URI will start a new instance of the app,
// a new window. That behavior, by default, doesn't align with iOS/Android/macOS, where
// the deeplink sends the event to the running app (if any). We are emulating it.
if hwnd, _ := windows.FindWindow(ID); hwnd != 0 {
if startupURI != "" {
broadcastURI(hwnd, startupURI)
if u := startupURI(); u != "" {
broadcastURI(hwnd, u)
}
os.Exit(0)
return
Expand All @@ -1090,6 +1080,13 @@ func init() {
go registerSchemes(ID, currentSchemes)
}

func startupURI() string {
if len(os.Args) == 3 && os.Args[1] == "-gio_launch_url" {
return os.Args[2]
}
return ""
}

func broadcastURI(hwnd syscall.Handle, uri string) {
u := syscall.StringToUTF16Ptr(uri)
msg := &windows.CopyDataStruct{
Expand Down Expand Up @@ -1223,5 +1220,3 @@ func unregisterSchemes(appid string, schemes []string) {
registry.DeleteKey(classes, scheme)
}
}

func (_ ViewEvent) ImplementsEvent() {}
1 change: 0 additions & 1 deletion app/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package app
import (
"errors"
"fmt"
"gioui.org/io/transfer"
"image"
"image/color"
"reflect"
Expand Down
16 changes: 16 additions & 0 deletions io/input/pointer.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type pointerFilter struct {

sourceMimes []string
targetMimes []string
scheme []string
}

type areaOp struct {
Expand Down Expand Up @@ -295,6 +296,14 @@ func (p *pointerFilter) Add(f event.Filter) {
}
}
p.targetMimes = append(p.targetMimes, f.Type)
case transfer.URLFilter:
for _, m := range p.scheme {
if m == f.Scheme {
return
}
}
p.scheme = append(p.scheme, f.Scheme)

case pointer.Filter:
p.kinds = p.kinds | f.Kinds
p.scrollX = p.scrollX.Union(f.ScrollX)
Expand All @@ -320,6 +329,12 @@ func (p *pointerFilter) Matches(e event.Event) bool {
return true
}
}
case transfer.URLEvent:
for _, t := range p.scheme {
if e.URL != nil && (t == "" || t == e.URL.Scheme) {
return true
}
}
}
return false
}
Expand All @@ -330,6 +345,7 @@ func (p *pointerFilter) Merge(p2 pointerFilter) {
p.scrollY = p.scrollY.Union(p2.scrollY)
p.sourceMimes = append(p.sourceMimes, p2.sourceMimes...)
p.targetMimes = append(p.targetMimes, p2.targetMimes...)
p.scheme = append(p.scheme, p2.scheme...)
}

// clampScroll splits a scroll distance in the remaining scroll and the
Expand Down
Loading

0 comments on commit ce5792f

Please sign in to comment.