app/internal/wm: change Options fields from values to pointers

Switching to pointer values in Options, including using window manager defaults for size and title, in preparation for updating options on the fly.

Signed-off-by: pierre <pierre.curto@gmail.com>
This commit is contained in:
pierre
2021-04-02 10:22:04 +02:00
committed by Elias Naur
parent 9d7b57f74a
commit 6330caad95
7 changed files with 110 additions and 61 deletions
+3 -1
View File
@@ -82,7 +82,9 @@ func NewWindow(win Callbacks, opts *Options) error {
}) })
w.addEventListeners() w.addEventListeners()
w.addHistory() w.addHistory()
w.windowMode(opts.WindowMode) if o := opts.WindowMode; o != nil {
w.windowMode(*o)
}
w.w = win w.w = win
go func() { go func() {
+25 -16
View File
@@ -338,25 +338,32 @@ func NewWindow(win Callbacks, opts *Options) error {
} }
screenScale := float32(C.gio_getScreenBackingScale()) screenScale := float32(C.gio_getScreenBackingScale())
cfg := configFor(screenScale) cfg := configFor(screenScale)
width := cfg.Px(opts.Width)
height := cfg.Px(opts.Height)
// Window sizes is in unscaled screen coordinates, not device pixels. // Window sizes is in unscaled screen coordinates, not device pixels.
width = int(float32(width) / screenScale) var width, height int
height = int(float32(height) / screenScale) if o := opts.Size; o != nil {
minWidth := cfg.Px(opts.MinWidth) width = int(float32(cfg.Px(o.Width)) / screenScale)
minHeight := cfg.Px(opts.MinHeight) height = int(float32(cfg.Px(o.Height)) / screenScale)
minWidth = int(float32(minWidth) / screenScale) }
minHeight = int(float32(minHeight) / screenScale) var minWidth, minHeight int
maxWidth := cfg.Px(opts.MaxWidth) if o := opts.MinSize; o != nil {
maxHeight := cfg.Px(opts.MaxHeight) minWidth = int(float32(cfg.Px(o.Width)) / screenScale)
maxWidth = int(float32(maxWidth) / screenScale) minHeight = int(float32(cfg.Px(o.Height)) / screenScale)
maxHeight = int(float32(maxHeight) / screenScale) }
title := C.CString(opts.Title) var maxWidth, maxHeight int
defer C.free(unsafe.Pointer(title)) if o := opts.MaxSize; o != nil {
maxWidth = int(float32(cfg.Px(o.Width)) / screenScale)
maxHeight = int(float32(cfg.Px(o.Height)) / screenScale)
}
var title string
if o := opts.Title; o != nil {
title = *o
}
ctitle := C.CString(title)
defer C.free(unsafe.Pointer(ctitle))
errch <- nil errch <- nil
win.SetDriver(w) win.SetDriver(w)
w.w = win w.w = win
w.window = C.gio_createWindow(w.view, title, C.CGFloat(width), C.CGFloat(height), w.window = C.gio_createWindow(w.view, ctitle, C.CGFloat(width), C.CGFloat(height),
C.CGFloat(minWidth), C.CGFloat(minHeight), C.CGFloat(maxWidth), C.CGFloat(maxHeight)) C.CGFloat(minWidth), C.CGFloat(minHeight), C.CGFloat(maxWidth), C.CGFloat(maxHeight))
if nextTopLeft.x == 0 && nextTopLeft.y == 0 { if nextTopLeft.x == 0 && nextTopLeft.y == 0 {
// cascadeTopLeftFromPoint treats (0, 0) as a no-op, // cascadeTopLeftFromPoint treats (0, 0) as a no-op,
@@ -365,7 +372,9 @@ func NewWindow(win Callbacks, opts *Options) error {
} }
nextTopLeft = C.gio_cascadeTopLeftFromPoint(w.window, nextTopLeft) nextTopLeft = C.gio_cascadeTopLeftFromPoint(w.window, nextTopLeft)
C.gio_makeKeyAndOrderFront(w.window) C.gio_makeKeyAndOrderFront(w.window)
w.SetWindowMode(opts.WindowMode) if o := opts.WindowMode; o != nil {
w.SetWindowMode(*o)
}
}) })
return <-errch return <-errch
} }
+10 -5
View File
@@ -356,13 +356,18 @@ func (d *wlDisplay) createNativeWindow(opts *Options) (*window, error) {
C.wl_surface_add_listener(w.surf, &C.gio_surface_listener, unsafe.Pointer(w.surf)) C.wl_surface_add_listener(w.surf, &C.gio_surface_listener, unsafe.Pointer(w.surf))
C.xdg_surface_add_listener(w.wmSurf, &C.gio_xdg_surface_listener, unsafe.Pointer(w.surf)) C.xdg_surface_add_listener(w.wmSurf, &C.gio_xdg_surface_listener, unsafe.Pointer(w.surf))
C.xdg_toplevel_add_listener(w.topLvl, &C.gio_xdg_toplevel_listener, unsafe.Pointer(w.surf)) C.xdg_toplevel_add_listener(w.topLvl, &C.gio_xdg_toplevel_listener, unsafe.Pointer(w.surf))
title := C.CString(opts.Title)
C.xdg_toplevel_set_title(w.topLvl, title) if o := opts.Title; o != nil {
C.free(unsafe.Pointer(title)) title := C.CString(*o)
C.xdg_toplevel_set_title(w.topLvl, title)
C.free(unsafe.Pointer(title))
}
_, _, cfg := w.config() _, _, cfg := w.config()
w.width = cfg.Px(opts.Width) if o := opts.Size; o != nil {
w.height = cfg.Px(opts.Height) w.width = cfg.Px(o.Width)
w.height = cfg.Px(o.Height)
}
if d.decor != nil { if d.decor != nil {
// Request server side decorations. // Request server side decorations.
w.decor = C.zxdg_decoration_manager_v1_get_toplevel_decoration(d.decor, w.topLvl) w.decor = C.zxdg_decoration_manager_v1_get_toplevel_decoration(d.decor, w.topLvl)
+21 -9
View File
@@ -122,7 +122,9 @@ func NewWindow(window Callbacks, opts *Options) error {
// Since the window class for the cursor is null, // Since the window class for the cursor is null,
// set it here to show the cursor. // set it here to show the cursor.
w.SetCursor(pointer.CursorDefault) w.SetCursor(pointer.CursorDefault)
w.SetWindowMode(opts.WindowMode) if o := opts.WindowMode; o != nil {
w.SetWindowMode(*o)
}
if err := w.loop(); err != nil { if err := w.loop(); err != nil {
panic(err) panic(err)
} }
@@ -162,10 +164,14 @@ func initResources() error {
func getWindowConstraints(cfg unit.Metric, opts *Options) winConstraints { func getWindowConstraints(cfg unit.Metric, opts *Options) winConstraints {
var minmax winConstraints var minmax winConstraints
minmax.minWidth = int32(cfg.Px(opts.MinWidth)) if o := opts.MinSize; o != nil {
minmax.minHeight = int32(cfg.Px(opts.MinHeight)) minmax.minWidth = int32(cfg.Px(o.Width))
minmax.maxWidth = int32(cfg.Px(opts.MaxWidth)) minmax.minHeight = int32(cfg.Px(o.Height))
minmax.maxHeight = int32(cfg.Px(opts.MaxHeight)) }
if o := opts.MaxSize; o != nil {
minmax.maxWidth = int32(cfg.Px(o.Width))
minmax.maxHeight = int32(cfg.Px(o.Height))
}
return minmax return minmax
} }
@@ -179,9 +185,10 @@ func createNativeWindow(opts *Options) (*window, error) {
} }
dpi := windows.GetSystemDPI() dpi := windows.GetSystemDPI()
cfg := configForDPI(dpi) cfg := configForDPI(dpi)
wr := windows.Rect{ var wr windows.Rect
Right: int32(cfg.Px(opts.Width)), if o := opts.Size; o != nil {
Bottom: int32(cfg.Px(opts.Height)), wr.Right = int32(cfg.Px(o.Width))
wr.Bottom = int32(cfg.Px(o.Height))
} }
dwStyle := uint32(windows.WS_OVERLAPPEDWINDOW) dwStyle := uint32(windows.WS_OVERLAPPEDWINDOW)
dwExStyle := uint32(windows.WS_EX_APPWINDOW | windows.WS_EX_WINDOWEDGE) dwExStyle := uint32(windows.WS_EX_APPWINDOW | windows.WS_EX_WINDOWEDGE)
@@ -193,9 +200,14 @@ func createNativeWindow(opts *Options) (*window, error) {
deltas.width = wr.Right - wr.Left - deltas.width deltas.width = wr.Right - wr.Left - deltas.width
deltas.height = wr.Bottom - wr.Top - deltas.height deltas.height = wr.Bottom - wr.Top - deltas.height
var title string
if o := opts.Title; o != nil {
title = *o
}
hwnd, err := windows.CreateWindowEx(dwExStyle, hwnd, err := windows.CreateWindowEx(dwExStyle,
resources.class, resources.class,
opts.Title, title,
dwStyle|windows.WS_CLIPSIBLINGS|windows.WS_CLIPCHILDREN, dwStyle|windows.WS_CLIPSIBLINGS|windows.WS_CLIPCHILDREN,
windows.CW_USEDEFAULT, windows.CW_USEDEFAULT, windows.CW_USEDEFAULT, windows.CW_USEDEFAULT,
wr.Right-wr.Left, wr.Right-wr.Left,
+23 -12
View File
@@ -576,15 +576,20 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
background_pixmap: C.None, background_pixmap: C.None,
override_redirect: C.False, override_redirect: C.False,
} }
var width, height int
if o := opts.Size; o != nil {
width = cfg.Px(o.Width)
height = cfg.Px(o.Height)
}
win := C.XCreateWindow(dpy, C.XDefaultRootWindow(dpy), win := C.XCreateWindow(dpy, C.XDefaultRootWindow(dpy),
0, 0, C.uint(cfg.Px(opts.Width)), C.uint(cfg.Px(opts.Height)), 0, 0, C.uint(width), C.uint(height),
0, C.CopyFromParent, C.InputOutput, nil, 0, C.CopyFromParent, C.InputOutput, nil,
C.CWEventMask|C.CWBackPixmap|C.CWOverrideRedirect, &swa) C.CWEventMask|C.CWBackPixmap|C.CWOverrideRedirect, &swa)
w := &x11Window{ w := &x11Window{
w: gioWin, x: dpy, xw: win, w: gioWin, x: dpy, xw: win,
width: cfg.Px(opts.Width), width: width,
height: cfg.Px(opts.Height), height: height,
cfg: cfg, cfg: cfg,
xkb: xkb, xkb: xkb,
xkbEventBase: xkbEventBase, xkbEventBase: xkbEventBase,
@@ -603,14 +608,14 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
C.XSetWMHints(dpy, win, &hints) C.XSetWMHints(dpy, win, &hints)
var shints C.XSizeHints var shints C.XSizeHints
if opts.MinWidth.V != 0 || opts.MinHeight.V != 0 { if o := opts.MinSize; o != nil && (o.Width.V != 0 || o.Height.V != 0) {
shints.min_width = C.int(cfg.Px(opts.MinWidth)) shints.min_width = C.int(cfg.Px(o.Width))
shints.min_height = C.int(cfg.Px(opts.MinHeight)) shints.min_height = C.int(cfg.Px(o.Height))
shints.flags = C.PMinSize shints.flags = C.PMinSize
} }
if opts.MaxWidth.V != 0 || opts.MaxHeight.V != 0 { if o := opts.MaxSize; o != nil && (o.Width.V != 0 || o.Height.V != 0) {
shints.max_width = C.int(cfg.Px(opts.MaxWidth)) shints.max_width = C.int(cfg.Px(o.Width))
shints.max_height = C.int(cfg.Px(opts.MaxHeight)) shints.max_height = C.int(cfg.Px(o.Height))
shints.flags = shints.flags | C.PMaxSize shints.flags = shints.flags | C.PMaxSize
} }
if shints.flags != 0 { if shints.flags != 0 {
@@ -635,7 +640,11 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
w.atoms.wmStateFullscreen = w.atom("_NET_WM_STATE_FULLSCREEN", false) w.atoms.wmStateFullscreen = w.atom("_NET_WM_STATE_FULLSCREEN", false)
// set the name // set the name
ctitle := C.CString(opts.Title) var title string
if o := opts.Title; o != nil {
title = *o
}
ctitle := C.CString(title)
defer C.free(unsafe.Pointer(ctitle)) defer C.free(unsafe.Pointer(ctitle))
C.XStoreName(dpy, win, ctitle) C.XStoreName(dpy, win, ctitle)
// set _NET_WM_NAME as well for UTF-8 support in window title. // set _NET_WM_NAME as well for UTF-8 support in window title.
@@ -644,14 +653,16 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
value: (*C.uchar)(unsafe.Pointer(ctitle)), value: (*C.uchar)(unsafe.Pointer(ctitle)),
encoding: w.atoms.utf8string, encoding: w.atoms.utf8string,
format: 8, format: 8,
nitems: C.ulong(len(opts.Title)), nitems: C.ulong(len(title)),
}, },
w.atoms.wmName) w.atoms.wmName)
// extensions // extensions
C.XSetWMProtocols(dpy, win, &w.atoms.evDelWindow, 1) C.XSetWMProtocols(dpy, win, &w.atoms.evDelWindow, 1)
w.SetWindowMode(opts.WindowMode) if o := opts.WindowMode; o != nil {
w.SetWindowMode(*o)
}
// make the window visible on the screen // make the window visible on the screen
C.XMapWindow(dpy, win) C.XMapWindow(dpy, win)
+10 -5
View File
@@ -14,12 +14,17 @@ import (
"gioui.org/unit" "gioui.org/unit"
) )
type Size struct {
Width unit.Value
Height unit.Value
}
type Options struct { type Options struct {
Width, Height unit.Value Size *Size
MinWidth, MinHeight unit.Value MinSize *Size
MaxWidth, MaxHeight unit.Value MaxSize *Size
Title string Title *string
WindowMode WindowMode WindowMode *WindowMode
} }
type WindowMode uint8 type WindowMode uint8
+18 -13
View File
@@ -84,11 +84,10 @@ var ackEvent event.Event
// Calling NewWindow more than once is not supported on // Calling NewWindow more than once is not supported on
// iOS, Android, WebAssembly. // iOS, Android, WebAssembly.
func NewWindow(options ...Option) *Window { func NewWindow(options ...Option) *Window {
opts := &wm.Options{ opts := new(wm.Options)
Width: unit.Dp(800), // Default options.
Height: unit.Dp(600), Size(unit.Px(800), unit.Px(600))(opts)
Title: "Gio", Title("Gio")(opts)
}
for _, o := range options { for _, o := range options {
o(opts) o(opts)
@@ -456,14 +455,14 @@ const (
// Supported platforms are macOS, X11 and Windows. // Supported platforms are macOS, X11 and Windows.
func WindowMode(mode wm.WindowMode) Option { func WindowMode(mode wm.WindowMode) Option {
return func(opts *wm.Options) { return func(opts *wm.Options) {
opts.WindowMode = mode opts.WindowMode = &mode
} }
} }
// Title sets the title of the wm. // Title sets the title of the wm.
func Title(t string) Option { func Title(t string) Option {
return func(opts *wm.Options) { return func(opts *wm.Options) {
opts.Title = t opts.Title = &t
} }
} }
@@ -476,8 +475,10 @@ func Size(w, h unit.Value) Option {
panic("height must be larger than or equal to 0") panic("height must be larger than or equal to 0")
} }
return func(opts *wm.Options) { return func(opts *wm.Options) {
opts.Width = w opts.Size = &wm.Size{
opts.Height = h Width: w,
Height: h,
}
} }
} }
@@ -490,8 +491,10 @@ func MaxSize(w, h unit.Value) Option {
panic("height must be larger than or equal to 0") panic("height must be larger than or equal to 0")
} }
return func(opts *wm.Options) { return func(opts *wm.Options) {
opts.MaxWidth = w opts.MaxSize = &wm.Size{
opts.MaxHeight = h Width: w,
Height: h,
}
} }
} }
@@ -504,8 +507,10 @@ func MinSize(w, h unit.Value) Option {
panic("height must be larger than or equal to 0") panic("height must be larger than or equal to 0")
} }
return func(opts *wm.Options) { return func(opts *wm.Options) {
opts.MinWidth = w opts.MinSize = &wm.Size{
opts.MinHeight = h Width: w,
Height: h,
}
} }
} }