~eliasnaur/gio

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
10 4

[PATCH gio 1/5] initial API

Details
Message ID
<160554234328.1949.11410491967671165499-0@git.sr.ht>
DKIM signature
missing
Download raw message
Patch: +32 -0
From: pierre <pierre.curto@gmail.com>

---
 app/internal/window/os_macos.go |  4 ++++
 app/internal/window/window.go   |  3 +++
 app/window.go                   |  7 +++++++
 io/pointer/pointer.go           | 18 ++++++++++++++++++
 4 files changed, 32 insertions(+)

diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go
index ef95b70..961aebd 100644
--- a/app/internal/window/os_macos.go
+++ b/app/internal/window/os_macos.go
@@ -122,6 +122,10 @@ func (w *window) WriteClipboard(s string) {
	})
}

func (w *window) SetCursor(name string) string {
	return ""
}

func (w *window) ShowTextInput(show bool) {}

func (w *window) SetAnimating(anim bool) {
diff --git a/app/internal/window/window.go b/app/internal/window/window.go
index 30ba360..e5bf11f 100644
--- a/app/internal/window/window.go
+++ b/app/internal/window/window.go
@@ -60,6 +60,9 @@ type Driver interface {
	// WriteClipboard requests a clipboard write.
	WriteClipboard(s string)

	// SetCursor updates the cursor in use and returns the current one.
	SetCursor(name string) string

	// Close the window.
	Close()
}
diff --git a/app/window.go b/app/window.go
index ed46958..62453da 100644
--- a/app/window.go
+++ b/app/window.go
@@ -5,6 +5,7 @@ package app
import (
	"errors"
	"fmt"
	"gioui.org/io/pointer"
	"image"
	"time"

@@ -209,6 +210,12 @@ func (w *Window) WriteClipboard(s string) {
	})
}

// SetCursorName changes the current window cursor to the one specified
// and returns the current one.
func (w *Window) SetCursorName(name pointer.CursorName) pointer.CursorName {
	return pointer.CursorName(w.driver.SetCursor(string(name)))
}

// Close the window. The window's event loop should exit when it receives
// system.DestroyEvent.
//
diff --git a/io/pointer/pointer.go b/io/pointer/pointer.go
index 3344d6b..44550e7 100644
--- a/io/pointer/pointer.go
+++ b/io/pointer/pointer.go
@@ -79,9 +79,27 @@ type Source uint8
// Buttons is a set of mouse buttons
type Buttons uint8

// CursorName is the name of a cursor.
type CursorName string

// Must match app/internal/input.areaKind
type areaKind uint8

const (
	// CursorArrow defines the default cursor.
	CursorArrow CursorName = "arrow"
	// CursorText defines the cursor to indicate text.
	CursorText CursorName = "text"
	// CursorPointer defines the cursor to indicate a link.
	CursorPointer CursorName = "pointer"
	// CursorMove defines the cursor to indicate moving an area.
	CursorMove CursorName = "move"
	// CursorVerticalResize defines the cursor to indicate vertical resize.
	CursorVerticalResize CursorName = "vertical resize"
	// CursorHorizontalResize defines the cursor to indicate horizontal resize.
	CursorHorizontalResize CursorName = "horizontal resize"
)

const (
	// A Cancel event is generated when the current gesture is
	// interrupted by other handlers or the system.
-- 
2.26.2

[PATCH gio 2/5] app.Window.SetCursor: implemented for macos

Details
Message ID
<160554234328.1949.11410491967671165499-1@git.sr.ht>
In-Reply-To
<160554234328.1949.11410491967671165499-0@git.sr.ht> (view parent)
DKIM signature
missing
Download raw message
Patch: +71 -11
From: pierre <pierre.curto@gmail.com>

Also added a section to the kitchen example to manipulate the cursor.
---
 app/internal/window/os_macos.go | 12 ++++++++++--
 app/internal/window/os_macos.m  | 24 ++++++++++++++++++++++++
 app/internal/window/window.go   |  5 +++--
 app/window.go                   |  6 ++++--
 example/go.mod                  |  2 ++
 example/kitchen/kitchen.go      | 33 ++++++++++++++++++++++++++++-----
 6 files changed, 71 insertions(+), 11 deletions(-)

diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go
index 961aebd..a41d488 100644
--- a/app/internal/window/os_macos.go
+++ b/app/internal/window/os_macos.go
@@ -38,6 +38,7 @@ __attribute__ ((visibility ("hidden"))) CGFloat gio_viewHeight(CFTypeRef viewRef
__attribute__ ((visibility ("hidden"))) CGFloat gio_getViewBackingScale(CFTypeRef viewRef);
__attribute__ ((visibility ("hidden"))) CGFloat gio_getScreenBackingScale(void);
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_readClipboard(void);
__attribute__ ((visibility ("hidden"))) void gio_setCursor(unichar *chars, NSUInteger length);
__attribute__ ((visibility ("hidden"))) void gio_writeClipboard(unichar *chars, NSUInteger length);
__attribute__ ((visibility ("hidden"))) void gio_setNeedsDisplay(CFTypeRef viewRef);
__attribute__ ((visibility ("hidden"))) CFTypeRef gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width, CGFloat height, CGFloat minWidth, CGFloat minHeight, CGFloat maxWidth, CGFloat maxHeight);
@@ -122,8 +123,15 @@ func (w *window) WriteClipboard(s string) {
	})
}

func (w *window) SetCursor(name string) string {
	return ""
func (w *window) SetCursor(s string) {
	u16 := utf16.Encode([]rune(s))
	runOnMain(func() {
		var chars *C.unichar
		if len(u16) > 0 {
			chars = (*C.unichar)(unsafe.Pointer(&u16[0]))
		}
		C.gio_setCursor(chars, C.NSUInteger(len(u16)))
	})
}

func (w *window) ShowTextInput(show bool) {}
diff --git a/app/internal/window/os_macos.m b/app/internal/window/os_macos.m
index b8c0dee..4183bdc 100644
--- a/app/internal/window/os_macos.m
+++ b/app/internal/window/os_macos.m
@@ -67,6 +67,30 @@ CFTypeRef gio_readClipboard(void) {
	}
}

void gio_setCursor(unichar *chars, NSUInteger length) {
    @autoreleasepool {
        NSString *s = [NSString string];
        if (length > 0) {
           s = [NSString stringWithCharacters:chars length:length];
        }
        if ([s isEqualToString: @"arrow"]) {
           [NSCursor.arrowCursor set];
        } else if ([s isEqualToString: @"text"]) {
           [NSCursor.IBeamCursor set];
        } else if ([s isEqualToString: @"pointer"]) {
           [NSCursor.pointingHandCursor set];
        } else if ([s isEqualToString: @"move"]) {
           [NSCursor.crosshairCursor set];
        } else if ([s isEqualToString: @"vertical resize"]) {
           [NSCursor.resizeLeftRightCursor set];
        } else if ([s isEqualToString: @"horizontal resize"]) {
           [NSCursor.resizeUpDownCursor set];
        } else {
            [NSCursor.arrowCursor set];
        }
    }
}

CGFloat gio_viewHeight(CFTypeRef viewRef) {
	NSView *view = (__bridge NSView *)viewRef;
	return [view bounds].size.height;
diff --git a/app/internal/window/window.go b/app/internal/window/window.go
index e5bf11f..375b494 100644
--- a/app/internal/window/window.go
+++ b/app/internal/window/window.go
@@ -60,8 +60,9 @@ type Driver interface {
	// WriteClipboard requests a clipboard write.
	WriteClipboard(s string)

	// SetCursor updates the cursor in use and returns the current one.
	SetCursor(name string) string
	// SetCursor updates the current cursor to name.
	// If name is invalid, the arrow cursor is used.
	SetCursor(name string)

	// Close the window.
	Close()
diff --git a/app/window.go b/app/window.go
index 62453da..0e75b70 100644
--- a/app/window.go
+++ b/app/window.go
@@ -212,8 +212,10 @@ func (w *Window) WriteClipboard(s string) {

// SetCursorName changes the current window cursor to the one specified
// and returns the current one.
func (w *Window) SetCursorName(name pointer.CursorName) pointer.CursorName {
	return pointer.CursorName(w.driver.SetCursor(string(name)))
func (w *Window) SetCursorName(name pointer.CursorName) {
	go w.driverDo(func() {
		w.driver.SetCursor(string(name))
	})
}

// Close the window. The window's event loop should exit when it receives
diff --git a/example/go.mod b/example/go.mod
index 9d8656d..f0b9071 100644
--- a/example/go.mod
+++ b/example/go.mod
@@ -11,3 +11,5 @@ require (
	golang.org/x/image v0.0.0-20200618115811-c13761719519
	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
)

replace gioui.org => ../
\ No newline at end of file
diff --git a/example/kitchen/kitchen.go b/example/kitchen/kitchen.go
index fb59eea..105dae9 100644
--- a/example/kitchen/kitchen.go
+++ b/example/kitchen/kitchen.go
@@ -15,12 +15,14 @@ import (
	"log"
	"math"
	"os"
	"strings"
	"time"

	"gioui.org/app"
	"gioui.org/app/headless"
	"gioui.org/f32"
	"gioui.org/font/gofont"
	"gioui.org/io/pointer"
	"gioui.org/io/router"
	"gioui.org/io/system"
	"gioui.org/layout"
@@ -96,7 +98,7 @@ func saveScreenshot(f string) error {
		Queue:       new(router.Router),
	}
	th := material.NewTheme(gofont.Collection())
	kitchen(gtx, th)
	kitchen(gtx, th, nil)
	w.Frame(gtx.Ops)
	img, err := w.Screenshot()
	if err != nil {
@@ -140,7 +142,7 @@ func loop(w *app.Window) error {
					}
				}

				transformedKitchen(gtx, th)
				transformedKitchen(gtx, th, w)
				e.Frame(gtx.Ops)
			}
		case p := <-progressIncrementer:
@@ -153,7 +155,7 @@ func loop(w *app.Window) error {
	}
}

func transformedKitchen(gtx layout.Context, th *material.Theme) layout.Dimensions {
func transformedKitchen(gtx layout.Context, th *material.Theme, w *app.Window) layout.Dimensions {
	if !transformTime.IsZero() {
		dt := float32(gtx.Now.Sub(transformTime).Seconds())
		angle := dt * .1
@@ -174,7 +176,7 @@ func transformedKitchen(gtx layout.Context, th *material.Theme) layout.Dimension
		op.Affine(tr).Add(gtx.Ops)
	}

	return kitchen(gtx, th)
	return kitchen(gtx, th, w)
}

var (
@@ -190,6 +192,7 @@ var (
	flatBtn           = new(widget.Clickable)
	disableBtn        = new(widget.Clickable)
	radioButtonsGroup = new(widget.Enum)
	cursorsGroup      = new(widget.Enum)
	list              = &layout.List{
		Axis: layout.Vertical,
	}
@@ -242,7 +245,7 @@ func (b iconAndTextButton) Layout(gtx layout.Context) layout.Dimensions {
	})
}

func kitchen(gtx layout.Context, th *material.Theme) layout.Dimensions {
func kitchen(gtx layout.Context, th *material.Theme, w *app.Window) layout.Dimensions {
	for _, e := range lineEditor.Events() {
		if e, ok := e.(widget.SubmitEvent); ok {
			topLabel = e.Text
@@ -375,6 +378,26 @@ func kitchen(gtx layout.Context, th *material.Theme) layout.Dimensions {
				}),
			)
		},
		func(gtx C) D {
			r := func(s string) layout.FlexChild {
				k := strings.ToLower(s)
				return layout.Rigid(func(gtx C) D {
					if w != nil && cursorsGroup.Changed() {
						w.SetCursorName(pointer.CursorName(cursorsGroup.Value))
					}
					return material.RadioButton(th, cursorsGroup, k, s).Layout(gtx)
				})
			}
			return layout.Flex{}.Layout(gtx,
				layout.Rigid(material.Body1(th, "Change cursor").Layout),
				r("Arrow"),
				r("Text"),
				r("Pointer"),
				r("Move"),
				r("Vertical resize"),
				r("Horizontal resize"),
			)
		},
	}

	return list.Layout(gtx, len(widgets), func(gtx C, i int) D {
-- 
2.26.2

[PATCH gio 3/5] app.Window.SetCursor: added support for windows.go

Details
Message ID
<160554234328.1949.11410491967671165499-2@git.sr.ht>
In-Reply-To
<160554234328.1949.11410491967671165499-0@git.sr.ht> (view parent)
DKIM signature
missing
Download raw message
Patch: +51 -11
From: Pierre.Curto <pierre.curto@gmail.com>

Removed unused field on app/internal/window.resources.
Also changed the name of the move cursor to crosshair.
---
 app/internal/window/os_macos.m    |  2 +-
 app/internal/window/os_windows.go | 41 ++++++++++++++++++++++++++-----
 app/internal/windows/windows.go   | 13 +++++++++-
 example/kitchen/kitchen.go        |  2 +-
 io/pointer/pointer.go             |  4 +--
 5 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/app/internal/window/os_macos.m b/app/internal/window/os_macos.m
index 4183bdc..debb8f9 100644
--- a/app/internal/window/os_macos.m
+++ b/app/internal/window/os_macos.m
@@ -79,7 +79,7 @@ void gio_setCursor(unichar *chars, NSUInteger length) {
           [NSCursor.IBeamCursor set];
        } else if ([s isEqualToString: @"pointer"]) {
           [NSCursor.pointingHandCursor set];
        } else if ([s isEqualToString: @"move"]) {
        } else if ([s isEqualToString: @"crosshair"]) {
           [NSCursor.crosshairCursor set];
        } else if ([s isEqualToString: @"vertical resize"]) {
           [NSCursor.resizeLeftRightCursor set];
diff --git a/app/internal/window/os_windows.go b/app/internal/window/os_windows.go
index edf7f54..49646c0 100644
--- a/app/internal/window/os_windows.go
+++ b/app/internal/window/os_windows.go
@@ -45,6 +45,7 @@ type window struct {
	height      int
	stage       system.Stage
	pointerBtns pointer.Buttons
	cursor      syscall.Handle

	mu        sync.Mutex
	animating bool
@@ -74,8 +75,6 @@ var resources struct {
	handle syscall.Handle
	// class is the Gio window class from RegisterClassEx.
	class uint16
	// cursor is the arrow cursor resource
	cursor syscall.Handle
}

func Main() {
@@ -105,6 +104,9 @@ func NewWindow(window Callbacks, opts *Options) error {
		windows.ShowWindow(w.hwnd, windows.SW_SHOWDEFAULT)
		windows.SetForegroundWindow(w.hwnd)
		windows.SetFocus(w.hwnd)
		// Since the window class for the cursor is null,
		// set it here to show the cursor.
		w.SetCursor("")
		if err := w.loop(); err != nil {
			panic(err)
		}
@@ -120,17 +122,17 @@ func initResources() error {
		return err
	}
	resources.handle = hInst
	curs, err := windows.LoadCursor(windows.IDC_ARROW)
	if err != nil {
	if _, err := windows.LoadCursor(windows.IDC_ARROW); err != nil {
		return err
	}
	resources.cursor = curs
	// Leave the HCursor class NULL to be able to change the cursor.
	// See the remarks here:
	// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setcursor
	wcls := windows.WndClassEx{
		CbSize:        uint32(unsafe.Sizeof(windows.WndClassEx{})),
		Style:         windows.CS_HREDRAW | windows.CS_VREDRAW | windows.CS_OWNDC,
		LpfnWndProc:   syscall.NewCallback(windowProc),
		HInstance:     hInst,
		HCursor:       curs,
		LpszClassName: syscall.StringToUTF16Ptr("GioWindow"),
	}
	cls, err := windows.RegisterClassEx(&wcls)
@@ -297,6 +299,8 @@ func windowProc(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) uintptr
				Y: w.minmax.maxHeight + w.deltas.height,
			}
		}
	case windows.WM_SETCURSOR:
		windows.SetCursor(w.cursor)
	}

	return windows.DefWindowProc(hwnd, msg, wParam, lParam)
@@ -546,6 +550,31 @@ func (w *window) writeClipboard(s string) error {
	return nil
}

func (w *window) SetCursor(name string) {
	var curID uint16
	switch name {
	case "arrow":
		curID = windows.IDC_ARROW
	case "text":
		curID = windows.IDC_IBEAM
	case "pointer":
		curID = windows.IDC_HAND
	case "crosshair":
		curID = windows.IDC_CROSS
	case "vertical resize":
		curID = windows.IDC_SIZENS
	case "horizontal resize":
		curID = windows.IDC_SIZEWE
	default:
		curID = windows.IDC_ARROW
	}
	c, err := windows.LoadCursor(curID)
	if err != nil {
		return
	}
	w.cursor = c
}

func (w *window) ShowTextInput(show bool) {}

func (w *window) HDC() syscall.Handle {
diff --git a/app/internal/windows/windows.go b/app/internal/windows/windows.go
index 29e7f99..087de0f 100644
--- a/app/internal/windows/windows.go
+++ b/app/internal/windows/windows.go
@@ -61,7 +61,12 @@ const (

	CW_USEDEFAULT = -2147483648

	IDC_ARROW = 32512
	IDC_ARROW  = 32512
	IDC_IBEAM  = 32513
	IDC_HAND   = 32649
	IDC_CROSS  = 32515
	IDC_SIZENS = 32645
	IDC_SIZEWE = 32644

	INFINITE = 0xFFFFFFFF

@@ -145,6 +150,7 @@ const (
	WM_PAINT         = 0x000F
	WM_CLOSE         = 0x0010
	WM_QUIT          = 0x0012
	WM_SETCURSOR     = 0x0020
	WM_SETFOCUS      = 0x0007
	WM_KILLFOCUS     = 0x0008
	WM_SHOWWINDOW    = 0x0018
@@ -226,6 +232,7 @@ var (
	_ScreenToClient              = user32.NewProc("ScreenToClient")
	_ShowWindow                  = user32.NewProc("ShowWindow")
	_SetCapture                  = user32.NewProc("SetCapture")
	_SetCursor                   = user32.NewProc("SetCursor")
	_SetClipboardData            = user32.NewProc("SetClipboardData")
	_SetForegroundWindow         = user32.NewProc("SetForegroundWindow")
	_SetFocus                    = user32.NewProc("SetFocus")
@@ -513,6 +520,10 @@ func SetClipboardData(format uint32, mem syscall.Handle) error {
	return nil
}

func SetCursor(h syscall.Handle) {
	_SetCursor.Call(uintptr(h))
}

func SetTimer(hwnd syscall.Handle, nIDEvent uintptr, uElapse uint32, timerProc uintptr) error {
	r, _, err := _SetTimer.Call(uintptr(hwnd), uintptr(nIDEvent), uintptr(uElapse), timerProc)
	if r == 0 {
diff --git a/example/kitchen/kitchen.go b/example/kitchen/kitchen.go
index 105dae9..6eea40f 100644
--- a/example/kitchen/kitchen.go
+++ b/example/kitchen/kitchen.go
@@ -393,7 +393,7 @@ func kitchen(gtx layout.Context, th *material.Theme, w *app.Window) layout.Dimen
				r("Arrow"),
				r("Text"),
				r("Pointer"),
				r("Move"),
				r("Crosshair"),
				r("Vertical resize"),
				r("Horizontal resize"),
			)
diff --git a/io/pointer/pointer.go b/io/pointer/pointer.go
index 44550e7..7fb6c9e 100644
--- a/io/pointer/pointer.go
+++ b/io/pointer/pointer.go
@@ -92,8 +92,8 @@ const (
	CursorText CursorName = "text"
	// CursorPointer defines the cursor to indicate a link.
	CursorPointer CursorName = "pointer"
	// CursorMove defines the cursor to indicate moving an area.
	CursorMove CursorName = "move"
	// CursorCrossHair defines the cursor to indicate precise location.
	CursorCrossHair CursorName = "crosshair"
	// CursorVerticalResize defines the cursor to indicate vertical resize.
	CursorVerticalResize CursorName = "vertical resize"
	// CursorHorizontalResize defines the cursor to indicate horizontal resize.
-- 
2.26.2

[PATCH gio 4/5] app.Window.SetCursor: stubs for android, ios, js, wayland and x11

Details
Message ID
<160554234328.1949.11410491967671165499-3@git.sr.ht>
In-Reply-To
<160554234328.1949.11410491967671165499-0@git.sr.ht> (view parent)
DKIM signature
missing
Download raw message
Patch: +18 -2
From: pierre <pierre.curto@gmail.com>

---
 app/internal/window/os_android.go | 2 ++
 app/internal/window/os_ios.go     | 2 ++
 app/internal/window/os_js.go      | 4 ++++
 app/internal/window/os_macos.go   | 4 ++--
 app/internal/window/os_wayland.go | 4 ++++
 app/internal/window/os_x11.go     | 4 ++++
 6 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/app/internal/window/os_android.go b/app/internal/window/os_android.go
index dac0bf3..d8031ba 100644
--- a/app/internal/window/os_android.go
+++ b/app/internal/window/os_android.go
@@ -392,6 +392,8 @@ func (w *window) SetAnimating(anim bool) {
	}
}

func (w *window) SetCursor(string) {}

func (w *window) draw(sync bool) {
	win := w.aNativeWindow()
	width, height := C.ANativeWindow_getWidth(win), C.ANativeWindow_getHeight(win)
diff --git a/app/internal/window/os_ios.go b/app/internal/window/os_ios.go
index 1865454..09140df 100644
--- a/app/internal/window/os_ios.go
+++ b/app/internal/window/os_ios.go
@@ -249,6 +249,8 @@ func (w *window) SetAnimating(anim bool) {
	}
}

func (w *window) SetCursor(string) {}

func (w *window) onKeyCommand(name string) {
	w.w.Event(key.Event{
		Name: name,
diff --git a/app/internal/window/os_js.go b/app/internal/window/os_js.go
index 7f3ffc5..9ff5e18 100644
--- a/app/internal/window/os_js.go
+++ b/app/internal/window/os_js.go
@@ -396,6 +396,10 @@ func (w *window) WriteClipboard(s string) {
	w.clipboard.Call("writeText", s)
}

func (w *window) SetCursor(name string) {
	//TODO SetCursor
}

func (w *window) ShowTextInput(show bool) {
	// Run in a goroutine to avoid a deadlock if the
	// focus change result in an event.
diff --git a/app/internal/window/os_macos.go b/app/internal/window/os_macos.go
index a41d488..c623371 100644
--- a/app/internal/window/os_macos.go
+++ b/app/internal/window/os_macos.go
@@ -123,8 +123,8 @@ func (w *window) WriteClipboard(s string) {
	})
}

func (w *window) SetCursor(s string) {
	u16 := utf16.Encode([]rune(s))
func (w *window) SetCursor(name string) {
	u16 := utf16.Encode([]rune(name))
	runOnMain(func() {
		var chars *C.unichar
		if len(u16) > 0 {
diff --git a/app/internal/window/os_wayland.go b/app/internal/window/os_wayland.go
index 60f59b1..9d80e61 100644
--- a/app/internal/window/os_wayland.go
+++ b/app/internal/window/os_wayland.go
@@ -917,6 +917,10 @@ func (w *window) WriteClipboard(s string) {
	w.disp.wakeup()
}

func (w *window) SetCursor(name string) {
	//TODO SetCursor
}

func (w *window) resetFling() {
	w.fling.start = false
	w.fling.anim = fling.Animation{}
diff --git a/app/internal/window/os_x11.go b/app/internal/window/os_x11.go
index 17bdd5a..9a6abb5 100644
--- a/app/internal/window/os_x11.go
+++ b/app/internal/window/os_x11.go
@@ -112,6 +112,10 @@ func (w *x11Window) WriteClipboard(s string) {
	w.wakeup()
}

func (w *x11Window) SetCursor(name string) {
	//TODO SetCursor
}

func (w *x11Window) ShowTextInput(show bool) {}

// Close the window.
-- 
2.26.2

[PATCH gio 5/5] app/Window.SetCursor: fixed comment

Details
Message ID
<160554234328.1949.11410491967671165499-4@git.sr.ht>
In-Reply-To
<160554234328.1949.11410491967671165499-0@git.sr.ht> (view parent)
DKIM signature
missing
Download raw message
Patch: +2 -3
From: pierre <pierre.curto@gmail.com>

---
 app/window.go | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/app/window.go b/app/window.go
index 0e75b70..deb719b 100644
--- a/app/window.go
+++ b/app/window.go
@@ -5,12 +5,12 @@ package app
import (
	"errors"
	"fmt"
	"gioui.org/io/pointer"
	"image"
	"time"

	"gioui.org/app/internal/window"
	"gioui.org/io/event"
	"gioui.org/io/pointer"
	"gioui.org/io/profile"
	"gioui.org/io/router"
	"gioui.org/io/system"
@@ -210,8 +210,7 @@ func (w *Window) WriteClipboard(s string) {
	})
}

// SetCursorName changes the current window cursor to the one specified
// and returns the current one.
// SetCursorName changes the current window cursor to name.
func (w *Window) SetCursorName(name pointer.CursorName) {
	go w.driverDo(func() {
		w.driver.SetCursor(string(name))
-- 
2.26.2
Details
Message ID
<C74TS6AID7DI.91LGAWWC8KJ5@themachine>
In-Reply-To
<160554234328.1949.11410491967671165499-0@git.sr.ht> (view parent)
DKIM signature
pass
Download raw message
Thanks for taking this on.

Please squash your changes so there are two logical commits: one for the
gioui.org module, and one for the example module. They need to be
separate because the example/go.mod needs updating before kitchen can
refer to the new API.

Use a more descriptive title for the API commit. For example:

app: add support for system cursors

On Sun Nov 15, 2020 at 20:31, ~pierrec wrote:
> From: pierre <pierre.curto@gmail.com>
>
> diff --git a/app/window.go b/app/window.go
> index ed46958..62453da 100644
> --- a/app/window.go
> +++ b/app/window.go
> @@ -209,6 +210,12 @@ func (w *Window) WriteClipboard(s string) {
>  	})
>  }
>  
> +// SetCursorName changes the current window cursor to the one specified
> +// and returns the current one.
> +func (w *Window) SetCursorName(name pointer.CursorName) pointer.CursorName {
> +	return pointer.CursorName(w.driver.SetCursor(string(name)))
> +}
> +
>  // Close the window. The window's event loop should exit when it receives
>  // system.DestroyEvent.
>  //
> diff --git a/io/pointer/pointer.go b/io/pointer/pointer.go
> index 3344d6b..44550e7 100644
> --- a/io/pointer/pointer.go
> +++ b/io/pointer/pointer.go
> @@ -79,9 +79,27 @@ type Source uint8
>  // Buttons is a set of mouse buttons
>  type Buttons uint8
>  
> +// CursorName is the name of a cursor.
> +type CursorName string
> +
>  // Must match app/internal/input.areaKind
>  type areaKind uint8
>  
> +const (
> +	// CursorArrow defines the default cursor.

"defines" doesn't seem fitting. How about

// CursorArrow is the default cursor.

> +	CursorArrow CursorName = "arrow"

I think we should match the browser names, and the string name should
match the constant name. So:

CursorDefault CursorName = "default"

Same below.

> +	// CursorText defines the cursor to indicate text.
> +	CursorText CursorName = "text"
> +	// CursorPointer defines the cursor to indicate a link.
> +	CursorPointer CursorName = "pointer"
> +	// CursorMove defines the cursor to indicate moving an area.
> +	CursorMove CursorName = "move"
> +	// CursorVerticalResize defines the cursor to indicate vertical resize.
> +	CursorVerticalResize CursorName = "vertical resize"
> +	// CursorHorizontalResize defines the cursor to indicate horizontal resize.
> +	CursorHorizontalResize CursorName = "horizontal resize"

Should there be a CursorNone for no cursor?

> +)

I think one of the cursor names should be the empty string to make the
zero CursorName value useful. I suggest CursorDefault because that's
what Window's cursor is if you haven't called SetCursor.

> +
>  const (
>  	// A Cancel event is generated when the current gesture is
>  	// interrupted by other handlers or the system.

Re: [PATCH gio 2/5] app.Window.SetCursor: implemented for macos

Details
Message ID
<C74U7NT055I6.1N3AOUNX2F5UP@themachine>
In-Reply-To
<160554234328.1949.11410491967671165499-1@git.sr.ht> (view parent)
DKIM signature
pass
Download raw message
On Mon Nov 16, 2020 at 09:21, ~pierrec wrote:
> From: pierre <pierre.curto@gmail.com>
>
> diff --git a/app/internal/window/os_macos.m b/app/internal/window/os_macos.m
> index b8c0dee..4183bdc 100644
> --- a/app/internal/window/os_macos.m
> +++ b/app/internal/window/os_macos.m
> @@ -67,6 +67,30 @@ CFTypeRef gio_readClipboard(void) {
>  	}
>  }
>  
> +void gio_setCursor(unichar *chars, NSUInteger length) {
> +    @autoreleasepool {
> +        NSString *s = [NSString string];
> +        if (length > 0) {
> +           s = [NSString stringWithCharacters:chars length:length];
> +        }
> +        if ([s isEqualToString: @"arrow"]) {
> +           [NSCursor.arrowCursor set];

The calls to NSCursor don't refer any particular view or window. How do
you ensure that the cursor is properly set when moving outside or
between windows. Looking at the example/windows example may be helpful.

> +        } else if ([s isEqualToString: @"text"]) {
> +           [NSCursor.IBeamCursor set];
> +        } else if ([s isEqualToString: @"pointer"]) {
> +           [NSCursor.pointingHandCursor set];
> +        } else if ([s isEqualToString: @"move"]) {
> +           [NSCursor.crosshairCursor set];
> +        } else if ([s isEqualToString: @"vertical resize"]) {
> +           [NSCursor.resizeLeftRightCursor set];
> +        } else if ([s isEqualToString: @"horizontal resize"]) {
> +           [NSCursor.resizeUpDownCursor set];
> +        } else {
> +            [NSCursor.arrowCursor set];
> +        }
> +    }
> +}
> +
>  CGFloat gio_viewHeight(CFTypeRef viewRef) {
>  	NSView *view = (__bridge NSView *)viewRef;
>  	return [view bounds].size.height;
> diff --git a/example/go.mod b/example/go.mod
> index 9d8656d..f0b9071 100644
> --- a/example/go.mod
> +++ b/example/go.mod
> @@ -11,3 +11,5 @@ require (
>  	golang.org/x/image v0.0.0-20200618115811-c13761719519
>  	golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
>  )
> +
> +replace gioui.org => ../

Drop this change from the commit you send (you can leave as a local
change for testing).

> \ No newline at end of file
> diff --git a/example/kitchen/kitchen.go b/example/kitchen/kitchen.go
> index fb59eea..105dae9 100644
> --- a/example/kitchen/kitchen.go
> +++ b/example/kitchen/kitchen.go
> @@ -375,6 +378,26 @@ func kitchen(gtx layout.Context, th *material.Theme) layout.Dimensions {
>  				}),
>  			)
>  		},
> +		func(gtx C) D {
> +			r := func(s string) layout.FlexChild {
> +				k := strings.ToLower(s)
> +				return layout.Rigid(func(gtx C) D {
> +					if w != nil && cursorsGroup.Changed() {
> +						w.SetCursorName(pointer.CursorName(cursorsGroup.Value))
> +					}

Move this check to loop to not do it once per option, and to avoid
passing the app.Window to kitchen.

> +					return material.RadioButton(th, cursorsGroup, k, s).Layout(gtx)
> +				})
> +			}
> +			return layout.Flex{}.Layout(gtx,
> +				layout.Rigid(material.Body1(th, "Change cursor").Layout),
> +				r("Arrow"),
> +				r("Text"),
> +				r("Pointer"),
> +				r("Move"),
> +				r("Vertical resize"),
> +				r("Horizontal resize"),
> +			)
> +		},
>  	}
>  
>  	return list.Layout(gtx, len(widgets), func(gtx C, i int) D {

Re: [PATCH gio 3/5] app.Window.SetCursor: added support for windows.go

Details
Message ID
<C74UE19F0J86.1C77ML4HUK5BC@themachine>
In-Reply-To
<160554234328.1949.11410491967671165499-2@git.sr.ht> (view parent)
DKIM signature
pass
Download raw message
On Mon Nov 16, 2020 at 14:06, ~pierrec wrote:
> From: Pierre.Curto <pierre.curto@gmail.com>
>
> Removed unused field on app/internal/window.resources.
> Also changed the name of the move cursor to crosshair.
> ---
>  app/internal/window/os_macos.m    |  2 +-
>  app/internal/window/os_windows.go | 41 ++++++++++++++++++++++++++-----
>  app/internal/windows/windows.go   | 13 +++++++++-
>  example/kitchen/kitchen.go        |  2 +-
>  io/pointer/pointer.go             |  4 +--
>  5 files changed, 51 insertions(+), 11 deletions(-)
>
> diff --git a/app/internal/window/os_macos.m b/app/internal/window/os_macos.m
> index 4183bdc..debb8f9 100644
> --- a/app/internal/window/os_macos.m
> +++ b/app/internal/window/os_macos.m
> @@ -79,7 +79,7 @@ void gio_setCursor(unichar *chars, NSUInteger length) {
>             [NSCursor.IBeamCursor set];
>          } else if ([s isEqualToString: @"pointer"]) {
>             [NSCursor.pointingHandCursor set];
> -        } else if ([s isEqualToString: @"move"]) {
> +        } else if ([s isEqualToString: @"crosshair"]) {
>             [NSCursor.crosshairCursor set];
>          } else if ([s isEqualToString: @"vertical resize"]) {
>             [NSCursor.resizeLeftRightCursor set];
> diff --git a/app/internal/window/os_windows.go b/app/internal/window/os_windows.go
> index edf7f54..49646c0 100644
> --- a/app/internal/window/os_windows.go
> +++ b/app/internal/window/os_windows.go
> @@ -45,6 +45,7 @@ type window struct {
>  	height      int
>  	stage       system.Stage
>  	pointerBtns pointer.Buttons
> +	cursor      syscall.Handle
>  
>  	mu        sync.Mutex
>  	animating bool
> @@ -74,8 +75,6 @@ var resources struct {
>  	handle syscall.Handle
>  	// class is the Gio window class from RegisterClassEx.
>  	class uint16
> -	// cursor is the arrow cursor resource
> -	cursor syscall.Handle
>  }
>  
>  func Main() {
> @@ -105,6 +104,9 @@ func NewWindow(window Callbacks, opts *Options) error {
>  		windows.ShowWindow(w.hwnd, windows.SW_SHOWDEFAULT)
>  		windows.SetForegroundWindow(w.hwnd)
>  		windows.SetFocus(w.hwnd)
> +		// Since the window class for the cursor is null,
> +		// set it here to show the cursor.

This seems like a platform-specific issue. Set up the default cursor in
the driver itself.

> +		w.SetCursor("")
>  		if err := w.loop(); err != nil {
>  			panic(err)
>  		}
> @@ -120,17 +122,17 @@ func initResources() error {
>  		return err
>  	}
>  	resources.handle = hInst
> -	curs, err := windows.LoadCursor(windows.IDC_ARROW)
> -	if err != nil {
> +	if _, err := windows.LoadCursor(windows.IDC_ARROW); err != nil {
>  		return err
>  	}
> -	resources.cursor = curs
> +	// Leave the HCursor class NULL to be able to change the cursor.
> +	// See the remarks here:
> +	// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setcursor

I don't think this needs commenting. Just delete the HCursor setting.

>  	wcls := windows.WndClassEx{
>  		CbSize:        uint32(unsafe.Sizeof(windows.WndClassEx{})),
>  		Style:         windows.CS_HREDRAW | windows.CS_VREDRAW | windows.CS_OWNDC,
>  		LpfnWndProc:   syscall.NewCallback(windowProc),
>  		HInstance:     hInst,
> -		HCursor:       curs,
>  		LpszClassName: syscall.StringToUTF16Ptr("GioWindow"),
>  	}
>  	cls, err := windows.RegisterClassEx(&wcls)
> @@ -546,6 +550,31 @@ func (w *window) writeClipboard(s string) error {
>  	return nil
>  }
>  
> +func (w *window) SetCursor(name string) {

Why not use pointer.CursorName here?

> +	var curID uint16
> +	switch name {
> +	case "arrow":

Why not use constants from package pointer here and below?

> +		curID = windows.IDC_ARROW
> +	case "text":
> +		curID = windows.IDC_IBEAM
> +	case "pointer":
> +		curID = windows.IDC_HAND
> +	case "crosshair":
> +		curID = windows.IDC_CROSS
> +	case "vertical resize":
> +		curID = windows.IDC_SIZENS
> +	case "horizontal resize":
> +		curID = windows.IDC_SIZEWE
> +	default:
> +		curID = windows.IDC_ARROW
> +	}
> +	c, err := windows.LoadCursor(curID)
> +	if err != nil {
> +		return
> +	}
> +	w.cursor = c
> +}
> +
>  func (w *window) ShowTextInput(show bool) {}
>  
>  func (w *window) HDC() syscall.Handle {

Re: [PATCH gio 4/5] app.Window.SetCursor: stubs for android, ios, js, wayland and x11

Details
Message ID
<C74UH8GG7P0S.MK27CDT3KHSL@themachine>
In-Reply-To
<160554234328.1949.11410491967671165499-3@git.sr.ht> (view parent)
DKIM signature
pass
Download raw message
Please add a comment to app.Window.SetCursor that lists the supported
platforms.

Re: [PATCH gio 4/5] app.Window.SetCursor: stubs for android, ios, js, wayland and x11

Details
Message ID
<CAG3idSf-X4EZbh3OR7vTMOaxn9Rgk4EeMMkQazEFqW=VMjnfZQ@mail.gmail.com>
In-Reply-To
<C74UH8GG7P0S.MK27CDT3KHSL@themachine> (view parent)
DKIM signature
pass
Download raw message
Will do, thanks!

Le lun. 16 nov. 2020 à 17:56, Elias Naur <mail@eliasnaur.com> a écrit :
>
> Please add a comment to app.Window.SetCursor that lists the supported
> platforms.

[gio/patches] build failed

builds.sr.ht <builds@sr.ht>
Details
Message ID
<C74WBVAOUFH8.1PBWJWQSZMZZO@cirno2>
In-Reply-To
<160554234328.1949.11410491967671165499-4@git.sr.ht> (view parent)
DKIM signature
missing
Download raw message
gio/patches: FAILED in 3m37s

[initial API][0] from [~pierrec][1]

[0]: https://lists.sr.ht/~eliasnaur/gio/patches/15066
[1]: pierre.curto@gmail.com

✗ #343871 FAILED gio/patches/linux.yml   https://builds.sr.ht/~eliasnaur/job/343871
✗ #343872 FAILED gio/patches/openbsd.yml https://builds.sr.ht/~eliasnaur/job/343872
✗ #343870 FAILED gio/patches/freebsd.yml https://builds.sr.ht/~eliasnaur/job/343870
✗ #343869 FAILED gio/patches/apple.yml   https://builds.sr.ht/~eliasnaur/job/343869
Reply to thread Export thread (mbox)