mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-06 01:45:36 +00:00
app/internal/wm: use Option method to initialize windows
Added (*w.window).Option methods to the backends and use them for setting the initial options passed into NewWindow. Signed-off-by: pierre <pierre.curto@gmail.com>
This commit is contained in:
@@ -271,6 +271,7 @@ var (
|
|||||||
_LoadImage = user32.NewProc("LoadImageW")
|
_LoadImage = user32.NewProc("LoadImageW")
|
||||||
_MonitorFromPoint = user32.NewProc("MonitorFromPoint")
|
_MonitorFromPoint = user32.NewProc("MonitorFromPoint")
|
||||||
_MonitorFromWindow = user32.NewProc("MonitorFromWindow")
|
_MonitorFromWindow = user32.NewProc("MonitorFromWindow")
|
||||||
|
_MoveWindow = user32.NewProc("MoveWindow")
|
||||||
_MsgWaitForMultipleObjectsEx = user32.NewProc("MsgWaitForMultipleObjectsEx")
|
_MsgWaitForMultipleObjectsEx = user32.NewProc("MsgWaitForMultipleObjectsEx")
|
||||||
_OpenClipboard = user32.NewProc("OpenClipboard")
|
_OpenClipboard = user32.NewProc("OpenClipboard")
|
||||||
_PeekMessage = user32.NewProc("PeekMessageW")
|
_PeekMessage = user32.NewProc("PeekMessageW")
|
||||||
@@ -289,8 +290,9 @@ var (
|
|||||||
_SetProcessDPIAware = user32.NewProc("SetProcessDPIAware")
|
_SetProcessDPIAware = user32.NewProc("SetProcessDPIAware")
|
||||||
_SetTimer = user32.NewProc("SetTimer")
|
_SetTimer = user32.NewProc("SetTimer")
|
||||||
_SetWindowLong = user32.NewProc("SetWindowLongPtrW")
|
_SetWindowLong = user32.NewProc("SetWindowLongPtrW")
|
||||||
_SetWindowPos = user32.NewProc("SetWindowPos")
|
|
||||||
_SetWindowPlacement = user32.NewProc("SetWindowPlacement")
|
_SetWindowPlacement = user32.NewProc("SetWindowPlacement")
|
||||||
|
_SetWindowPos = user32.NewProc("SetWindowPos")
|
||||||
|
_SetWindowText = user32.NewProc("SetWindowTextW")
|
||||||
_TranslateMessage = user32.NewProc("TranslateMessage")
|
_TranslateMessage = user32.NewProc("TranslateMessage")
|
||||||
_UnregisterClass = user32.NewProc("UnregisterClassW")
|
_UnregisterClass = user32.NewProc("UnregisterClassW")
|
||||||
_UpdateWindow = user32.NewProc("UpdateWindow")
|
_UpdateWindow = user32.NewProc("UpdateWindow")
|
||||||
@@ -486,6 +488,11 @@ func SetWindowPos(hwnd syscall.Handle, hwndInsertAfter uint32, x, y, dx, dy int3
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetWindowText(hwnd syscall.Handle, title string) {
|
||||||
|
wname := syscall.StringToUTF16Ptr(title)
|
||||||
|
_SetWindowText.Call(uintptr(hwnd), uintptr(unsafe.Pointer(wname)))
|
||||||
|
}
|
||||||
|
|
||||||
func GlobalAlloc(size int) (syscall.Handle, error) {
|
func GlobalAlloc(size int) (syscall.Handle, error) {
|
||||||
r, _, err := _GlobalAlloc.Call(GHND, uintptr(size))
|
r, _, err := _GlobalAlloc.Call(GHND, uintptr(size))
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
@@ -534,6 +541,14 @@ func LoadImage(hInst syscall.Handle, res uint32, typ uint32, cx, cy int, fuload
|
|||||||
return syscall.Handle(h), nil
|
return syscall.Handle(h), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MoveWindow(hwnd syscall.Handle, x, y, width, height int32, repaint bool) {
|
||||||
|
var paint uintptr
|
||||||
|
if repaint {
|
||||||
|
paint = TRUE
|
||||||
|
}
|
||||||
|
_MoveWindow.Call(uintptr(hwnd), uintptr(x), uintptr(y), uintptr(width), uintptr(height), paint)
|
||||||
|
}
|
||||||
|
|
||||||
func monitorFromPoint(pt Point, flags uint32) syscall.Handle {
|
func monitorFromPoint(pt Point, flags uint32) syscall.Handle {
|
||||||
r, _, _ := _MonitorFromPoint.Call(uintptr(pt.X), uintptr(pt.Y), uintptr(flags))
|
r, _, _ := _MonitorFromPoint.Call(uintptr(pt.X), uintptr(pt.Y), uintptr(flags))
|
||||||
return syscall.Handle(r)
|
return syscall.Handle(r)
|
||||||
|
|||||||
@@ -676,6 +676,8 @@ func (w *window) ReadClipboard() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *window) Option(opts *Options) {}
|
||||||
|
|
||||||
func (w *window) SetCursor(name pointer.CursorName) {
|
func (w *window) SetCursor(name pointer.CursorName) {
|
||||||
w.setState(func(state *windowState) {
|
w.setState(func(state *windowState) {
|
||||||
state.cursor = &name
|
state.cursor = &name
|
||||||
|
|||||||
@@ -239,6 +239,8 @@ func (w *window) WriteClipboard(s string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *window) Option(opts *Options) {}
|
||||||
|
|
||||||
func (w *window) SetAnimating(anim bool) {
|
func (w *window) SetAnimating(anim bool) {
|
||||||
v := w.view
|
v := w.view
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
|
|||||||
@@ -82,9 +82,7 @@ func NewWindow(win Callbacks, opts *Options) error {
|
|||||||
})
|
})
|
||||||
w.addEventListeners()
|
w.addEventListeners()
|
||||||
w.addHistory()
|
w.addHistory()
|
||||||
if o := opts.WindowMode; o != nil {
|
w.Option(opts)
|
||||||
w.windowMode(*o)
|
|
||||||
}
|
|
||||||
w.w = win
|
w.w = win
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -476,6 +474,12 @@ func (w *window) WriteClipboard(s string) {
|
|||||||
w.clipboard.Call("writeText", s)
|
w.clipboard.Call("writeText", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *window) Option(opts *Options) {
|
||||||
|
if o := opts.WindowMode; o != nil {
|
||||||
|
w.windowMode(*o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *window) SetCursor(name pointer.CursorName) {
|
func (w *window) SetCursor(name pointer.CursorName) {
|
||||||
style := w.cnv.Get("style")
|
style := w.cnv.Get("style")
|
||||||
style.Set("cursor", string(name))
|
style.Set("cursor", string(name))
|
||||||
|
|||||||
+55
-35
@@ -46,6 +46,10 @@ __attribute__ ((visibility ("hidden"))) CFTypeRef gio_createWindow(CFTypeRef vie
|
|||||||
__attribute__ ((visibility ("hidden"))) void gio_makeKeyAndOrderFront(CFTypeRef windowRef);
|
__attribute__ ((visibility ("hidden"))) void gio_makeKeyAndOrderFront(CFTypeRef windowRef);
|
||||||
__attribute__ ((visibility ("hidden"))) NSPoint gio_cascadeTopLeftFromPoint(CFTypeRef windowRef, NSPoint topLeft);
|
__attribute__ ((visibility ("hidden"))) NSPoint gio_cascadeTopLeftFromPoint(CFTypeRef windowRef, NSPoint topLeft);
|
||||||
__attribute__ ((visibility ("hidden"))) void gio_close(CFTypeRef windowRef);
|
__attribute__ ((visibility ("hidden"))) void gio_close(CFTypeRef windowRef);
|
||||||
|
__attribute__ ((visibility ("hidden"))) void gio_setSize(CFTypeRef windowRef, CGFloat width, CGFloat height);
|
||||||
|
__attribute__ ((visibility ("hidden"))) void gio_setMinSize(CFTypeRef windowRef, CGFloat width, CGFloat height);
|
||||||
|
__attribute__ ((visibility ("hidden"))) void gio_setMaxSize(CFTypeRef windowRef, CGFloat width, CGFloat height);
|
||||||
|
__attribute__ ((visibility ("hidden"))) void gio_setTitle(CFTypeRef windowRef, const char *title);
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
@@ -126,6 +130,45 @@ func (w *window) WriteClipboard(s string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *window) Option(opts *Options) {
|
||||||
|
w.runOnMain(func() {
|
||||||
|
screenScale := float32(C.gio_getScreenBackingScale())
|
||||||
|
cfg := configFor(screenScale)
|
||||||
|
val := func(v unit.Value) float32 {
|
||||||
|
return float32(cfg.Px(v)) / screenScale
|
||||||
|
}
|
||||||
|
if o := opts.Size; o != nil {
|
||||||
|
width := val(o.Width)
|
||||||
|
height := val(o.Height)
|
||||||
|
if width > 0 || height > 0 {
|
||||||
|
C.gio_setSize(w.window, C.CGFloat(width), C.CGFloat(height))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if o := opts.MinSize; o != nil {
|
||||||
|
width := val(o.Width)
|
||||||
|
height := val(o.Height)
|
||||||
|
if width > 0 || height > 0 {
|
||||||
|
C.gio_setMinSize(w.window, C.CGFloat(width), C.CGFloat(height))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if o := opts.MaxSize; o != nil {
|
||||||
|
width := val(o.Width)
|
||||||
|
height := val(o.Height)
|
||||||
|
if width > 0 || height > 0 {
|
||||||
|
C.gio_setMaxSize(w.window, C.CGFloat(width), C.CGFloat(height))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if o := opts.Title; o != nil {
|
||||||
|
title := C.CString(*o)
|
||||||
|
defer C.free(unsafe.Pointer(title))
|
||||||
|
C.gio_setTitle(w.window, title)
|
||||||
|
}
|
||||||
|
if o := opts.WindowMode; o != nil {
|
||||||
|
w.SetWindowMode(*o)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (w *window) SetWindowMode(mode WindowMode) {
|
func (w *window) SetWindowMode(mode WindowMode) {
|
||||||
switch mode {
|
switch mode {
|
||||||
case w.mode:
|
case w.mode:
|
||||||
@@ -150,16 +193,22 @@ func (w *window) SetAnimating(anim bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *window) Close() {
|
func (w *window) runOnMain(f func()) {
|
||||||
runOnMain(func() {
|
runOnMain(func() {
|
||||||
// Make sure the view is still valid. The window might've been closed
|
// Make sure the view is still valid. The window might've been closed
|
||||||
// during the switch to the main thread.
|
// during the switch to the main thread.
|
||||||
if w.view != 0 {
|
if w.view != 0 {
|
||||||
C.gio_close(w.window)
|
f()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *window) Close() {
|
||||||
|
w.runOnMain(func() {
|
||||||
|
C.gio_close(w.window)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (w *window) setStage(stage system.Stage) {
|
func (w *window) setStage(stage system.Stage) {
|
||||||
if stage == w.stage {
|
if stage == w.stage {
|
||||||
return
|
return
|
||||||
@@ -336,35 +385,11 @@ func NewWindow(win Callbacks, opts *Options) error {
|
|||||||
errch <- err
|
errch <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
screenScale := float32(C.gio_getScreenBackingScale())
|
|
||||||
cfg := configFor(screenScale)
|
|
||||||
// Window sizes is in unscaled screen coordinates, not device pixels.
|
|
||||||
var width, height int
|
|
||||||
if o := opts.Size; o != nil {
|
|
||||||
width = int(float32(cfg.Px(o.Width)) / screenScale)
|
|
||||||
height = int(float32(cfg.Px(o.Height)) / screenScale)
|
|
||||||
}
|
|
||||||
var minWidth, minHeight int
|
|
||||||
if o := opts.MinSize; o != nil {
|
|
||||||
minWidth = int(float32(cfg.Px(o.Width)) / screenScale)
|
|
||||||
minHeight = int(float32(cfg.Px(o.Height)) / screenScale)
|
|
||||||
}
|
|
||||||
var maxWidth, maxHeight int
|
|
||||||
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, ctitle, C.CGFloat(width), C.CGFloat(height),
|
w.window = C.gio_createWindow(w.view, nil, 0, 0, 0, 0, 0, 0)
|
||||||
C.CGFloat(minWidth), C.CGFloat(minHeight), C.CGFloat(maxWidth), C.CGFloat(maxHeight))
|
w.Option(opts)
|
||||||
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,
|
||||||
// and just returns the offset we need for the first window.
|
// and just returns the offset we need for the first window.
|
||||||
@@ -372,9 +397,6 @@ 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)
|
||||||
if o := opts.WindowMode; o != nil {
|
|
||||||
w.SetWindowMode(*o)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return <-errch
|
return <-errch
|
||||||
}
|
}
|
||||||
@@ -390,10 +412,8 @@ func newWindow(opts *Options) (*window, error) {
|
|||||||
scale: scale,
|
scale: scale,
|
||||||
}
|
}
|
||||||
dl, err := NewDisplayLink(func() {
|
dl, err := NewDisplayLink(func() {
|
||||||
runOnMain(func() {
|
w.runOnMain(func() {
|
||||||
if w.view != 0 {
|
C.gio_setNeedsDisplay(w.view)
|
||||||
C.gio_setNeedsDisplay(w.view)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
w.displayLink = dl
|
w.displayLink = dl
|
||||||
|
|||||||
@@ -191,7 +191,9 @@ CFTypeRef gio_createWindow(CFTypeRef viewRef, const char *title, CGFloat width,
|
|||||||
window.contentMaxSize = NSMakeSize(maxWidth, maxHeight);
|
window.contentMaxSize = NSMakeSize(maxWidth, maxHeight);
|
||||||
}
|
}
|
||||||
[window setAcceptsMouseMovedEvents:YES];
|
[window setAcceptsMouseMovedEvents:YES];
|
||||||
window.title = [NSString stringWithUTF8String: title];
|
if (title != nil) {
|
||||||
|
window.title = [NSString stringWithUTF8String: title];
|
||||||
|
}
|
||||||
NSView *view = (__bridge NSView *)viewRef;
|
NSView *view = (__bridge NSView *)viewRef;
|
||||||
[window setContentView:view];
|
[window setContentView:view];
|
||||||
[window makeFirstResponder:view];
|
[window makeFirstResponder:view];
|
||||||
@@ -206,6 +208,27 @@ void gio_close(CFTypeRef windowRef) {
|
|||||||
[window performClose:nil];
|
[window performClose:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gio_setSize(CFTypeRef windowRef, CGFloat width, CGFloat height) {
|
||||||
|
NSWindow* window = (__bridge NSWindow *)windowRef;
|
||||||
|
NSSize size = NSMakeSize(width, height);
|
||||||
|
[window setContentSize:size];
|
||||||
|
}
|
||||||
|
|
||||||
|
void gio_setMinSize(CFTypeRef windowRef, CGFloat width, CGFloat height) {
|
||||||
|
NSWindow* window = (__bridge NSWindow *)windowRef;
|
||||||
|
window.contentMinSize = NSMakeSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gio_setMaxSize(CFTypeRef windowRef, CGFloat width, CGFloat height) {
|
||||||
|
NSWindow* window = (__bridge NSWindow *)windowRef;
|
||||||
|
window.contentMaxSize = NSMakeSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gio_setTitle(CFTypeRef windowRef, const char *title) {
|
||||||
|
NSWindow* window = (__bridge NSWindow *)windowRef;
|
||||||
|
window.title = [NSString stringWithUTF8String: title];
|
||||||
|
}
|
||||||
|
|
||||||
@implementation GioAppDelegate
|
@implementation GioAppDelegate
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||||
[[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)];
|
[[NSRunningApplication currentApplication] activateWithOptions:(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)];
|
||||||
|
|||||||
@@ -357,17 +357,8 @@ func (d *wlDisplay) createNativeWindow(opts *Options) (*window, error) {
|
|||||||
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))
|
||||||
|
|
||||||
if o := opts.Title; o != nil {
|
w.Option(opts)
|
||||||
title := C.CString(*o)
|
|
||||||
C.xdg_toplevel_set_title(w.topLvl, title)
|
|
||||||
C.free(unsafe.Pointer(title))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, cfg := w.config()
|
|
||||||
if o := opts.Size; o != nil {
|
|
||||||
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)
|
||||||
@@ -918,6 +909,19 @@ func (w *window) WriteClipboard(s string) {
|
|||||||
w.disp.wakeup()
|
w.disp.wakeup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *window) Option(opts *Options) {
|
||||||
|
_, _, cfg := w.config()
|
||||||
|
if o := opts.Size; o != nil {
|
||||||
|
w.width = cfg.Px(o.Width)
|
||||||
|
w.height = cfg.Px(o.Height)
|
||||||
|
}
|
||||||
|
if o := opts.Title; o != nil {
|
||||||
|
title := C.CString(*o)
|
||||||
|
C.xdg_toplevel_set_title(w.topLvl, title)
|
||||||
|
C.free(unsafe.Pointer(title))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *window) SetCursor(name pointer.CursorName) {
|
func (w *window) SetCursor(name pointer.CursorName) {
|
||||||
if name == pointer.CursorNone {
|
if name == pointer.CursorNone {
|
||||||
C.wl_pointer_set_cursor(w.disp.seat.pointer, w.serial, nil, 0, 0)
|
C.wl_pointer_set_cursor(w.disp.seat.pointer, w.serial, nil, 0, 0)
|
||||||
|
|||||||
@@ -116,15 +116,13 @@ func NewWindow(window Callbacks, opts *Options) error {
|
|||||||
w.w = window
|
w.w = window
|
||||||
w.w.SetDriver(w)
|
w.w.SetDriver(w)
|
||||||
defer w.w.Event(system.DestroyEvent{})
|
defer w.w.Event(system.DestroyEvent{})
|
||||||
|
w.Option(opts)
|
||||||
windows.ShowWindow(w.hwnd, windows.SW_SHOWDEFAULT)
|
windows.ShowWindow(w.hwnd, windows.SW_SHOWDEFAULT)
|
||||||
windows.SetForegroundWindow(w.hwnd)
|
windows.SetForegroundWindow(w.hwnd)
|
||||||
windows.SetFocus(w.hwnd)
|
windows.SetFocus(w.hwnd)
|
||||||
// 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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
@@ -185,33 +183,15 @@ func createNativeWindow(opts *Options) (*window, error) {
|
|||||||
}
|
}
|
||||||
dpi := windows.GetSystemDPI()
|
dpi := windows.GetSystemDPI()
|
||||||
cfg := configForDPI(dpi)
|
cfg := configForDPI(dpi)
|
||||||
var wr windows.Rect
|
|
||||||
if o := opts.Size; o != nil {
|
|
||||||
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)
|
||||||
deltas := winDeltas{
|
|
||||||
width: wr.Right,
|
|
||||||
height: wr.Bottom,
|
|
||||||
}
|
|
||||||
windows.AdjustWindowRectEx(&wr, dwStyle, 0, dwExStyle)
|
|
||||||
deltas.width = wr.Right - wr.Left - deltas.width
|
|
||||||
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,
|
||||||
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,
|
windows.CW_USEDEFAULT, windows.CW_USEDEFAULT,
|
||||||
wr.Bottom-wr.Top,
|
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
resources.handle,
|
resources.handle,
|
||||||
@@ -222,7 +202,6 @@ func createNativeWindow(opts *Options) (*window, error) {
|
|||||||
w := &window{
|
w := &window{
|
||||||
hwnd: hwnd,
|
hwnd: hwnd,
|
||||||
minmax: getWindowConstraints(cfg, opts),
|
minmax: getWindowConstraints(cfg, opts),
|
||||||
deltas: deltas,
|
|
||||||
opts: opts,
|
opts: opts,
|
||||||
}
|
}
|
||||||
w.hdc, err = windows.GetDC(hwnd)
|
w.hdc, err = windows.GetDC(hwnd)
|
||||||
@@ -540,6 +519,45 @@ func (w *window) readClipboard() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *window) Option(opts *Options) {
|
||||||
|
if o := opts.Size; o != nil {
|
||||||
|
dpi := windows.GetSystemDPI()
|
||||||
|
cfg := configForDPI(dpi)
|
||||||
|
width := int32(cfg.Px(o.Width))
|
||||||
|
height := int32(cfg.Px(o.Height))
|
||||||
|
|
||||||
|
// Include the window decorations.
|
||||||
|
wr := windows.Rect{
|
||||||
|
Right: width,
|
||||||
|
Bottom: height,
|
||||||
|
}
|
||||||
|
dwStyle := uint32(windows.WS_OVERLAPPEDWINDOW)
|
||||||
|
dwExStyle := uint32(windows.WS_EX_APPWINDOW | windows.WS_EX_WINDOWEDGE)
|
||||||
|
windows.AdjustWindowRectEx(&wr, dwStyle, 0, dwExStyle)
|
||||||
|
|
||||||
|
dw, dh := width, height
|
||||||
|
width = wr.Right - wr.Left
|
||||||
|
height = wr.Bottom - wr.Top
|
||||||
|
w.deltas.width = width - dw
|
||||||
|
w.deltas.height = height - dh
|
||||||
|
|
||||||
|
w.opts.Size = o
|
||||||
|
windows.MoveWindow(w.hwnd, 0, 0, width, height, true)
|
||||||
|
}
|
||||||
|
if o := opts.MinSize; o != nil {
|
||||||
|
w.opts.MinSize = o
|
||||||
|
}
|
||||||
|
if o := opts.MaxSize; o != nil {
|
||||||
|
w.opts.MaxSize = o
|
||||||
|
}
|
||||||
|
if o := opts.Title; o != nil {
|
||||||
|
windows.SetWindowText(w.hwnd, *opts.Title)
|
||||||
|
}
|
||||||
|
if o := opts.WindowMode; o != nil {
|
||||||
|
w.SetWindowMode(*o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *window) SetWindowMode(mode WindowMode) {
|
func (w *window) SetWindowMode(mode WindowMode) {
|
||||||
// https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
|
// https://devblogs.microsoft.com/oldnewthing/20100412-00/?p=14353
|
||||||
switch mode {
|
switch mode {
|
||||||
|
|||||||
+42
-36
@@ -123,6 +123,47 @@ func (w *x11Window) WriteClipboard(s string) {
|
|||||||
w.wakeup()
|
w.wakeup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *x11Window) Option(opts *Options) {
|
||||||
|
dpy := w.x
|
||||||
|
win := w.xw
|
||||||
|
cfg := w.cfg
|
||||||
|
var shints C.XSizeHints
|
||||||
|
if o := opts.MinSize; o != nil {
|
||||||
|
shints.min_width = C.int(cfg.Px(o.Width))
|
||||||
|
shints.min_height = C.int(cfg.Px(o.Height))
|
||||||
|
shints.flags = C.PMinSize
|
||||||
|
}
|
||||||
|
if o := opts.MaxSize; o != nil {
|
||||||
|
shints.max_width = C.int(cfg.Px(o.Width))
|
||||||
|
shints.max_height = C.int(cfg.Px(o.Height))
|
||||||
|
shints.flags = shints.flags | C.PMaxSize
|
||||||
|
}
|
||||||
|
if shints.flags != 0 {
|
||||||
|
C.XSetWMNormalHints(dpy, win, &shints)
|
||||||
|
}
|
||||||
|
|
||||||
|
var title string
|
||||||
|
if o := opts.Title; o != nil {
|
||||||
|
title = *o
|
||||||
|
}
|
||||||
|
ctitle := C.CString(title)
|
||||||
|
defer C.free(unsafe.Pointer(ctitle))
|
||||||
|
C.XStoreName(dpy, win, ctitle)
|
||||||
|
// set _NET_WM_NAME as well for UTF-8 support in window title.
|
||||||
|
C.XSetTextProperty(dpy, win,
|
||||||
|
&C.XTextProperty{
|
||||||
|
value: (*C.uchar)(unsafe.Pointer(ctitle)),
|
||||||
|
encoding: w.atoms.utf8string,
|
||||||
|
format: 8,
|
||||||
|
nitems: C.ulong(len(title)),
|
||||||
|
},
|
||||||
|
w.atoms.wmName)
|
||||||
|
|
||||||
|
if o := opts.WindowMode; o != nil {
|
||||||
|
w.SetWindowMode(*o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *x11Window) SetCursor(name pointer.CursorName) {
|
func (w *x11Window) SetCursor(name pointer.CursorName) {
|
||||||
switch name {
|
switch name {
|
||||||
case pointer.CursorNone:
|
case pointer.CursorNone:
|
||||||
@@ -607,21 +648,6 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
|
|||||||
hints.flags = C.InputHint
|
hints.flags = C.InputHint
|
||||||
C.XSetWMHints(dpy, win, &hints)
|
C.XSetWMHints(dpy, win, &hints)
|
||||||
|
|
||||||
var shints C.XSizeHints
|
|
||||||
if o := opts.MinSize; o != nil && (o.Width.V != 0 || o.Height.V != 0) {
|
|
||||||
shints.min_width = C.int(cfg.Px(o.Width))
|
|
||||||
shints.min_height = C.int(cfg.Px(o.Height))
|
|
||||||
shints.flags = C.PMinSize
|
|
||||||
}
|
|
||||||
if o := opts.MaxSize; o != nil && (o.Width.V != 0 || o.Height.V != 0) {
|
|
||||||
shints.max_width = C.int(cfg.Px(o.Width))
|
|
||||||
shints.max_height = C.int(cfg.Px(o.Height))
|
|
||||||
shints.flags = shints.flags | C.PMaxSize
|
|
||||||
}
|
|
||||||
if shints.flags != 0 {
|
|
||||||
C.XSetWMNormalHints(dpy, win, &shints)
|
|
||||||
}
|
|
||||||
|
|
||||||
name := C.CString(filepath.Base(os.Args[0]))
|
name := C.CString(filepath.Base(os.Args[0]))
|
||||||
defer C.free(unsafe.Pointer(name))
|
defer C.free(unsafe.Pointer(name))
|
||||||
wmhints := C.XClassHint{name, name}
|
wmhints := C.XClassHint{name, name}
|
||||||
@@ -639,30 +665,10 @@ func newX11Window(gioWin Callbacks, opts *Options) error {
|
|||||||
w.atoms.wmState = w.atom("_NET_WM_STATE", false)
|
w.atoms.wmState = w.atom("_NET_WM_STATE", false)
|
||||||
w.atoms.wmStateFullscreen = w.atom("_NET_WM_STATE_FULLSCREEN", false)
|
w.atoms.wmStateFullscreen = w.atom("_NET_WM_STATE_FULLSCREEN", false)
|
||||||
|
|
||||||
// set the name
|
|
||||||
var title string
|
|
||||||
if o := opts.Title; o != nil {
|
|
||||||
title = *o
|
|
||||||
}
|
|
||||||
ctitle := C.CString(title)
|
|
||||||
defer C.free(unsafe.Pointer(ctitle))
|
|
||||||
C.XStoreName(dpy, win, ctitle)
|
|
||||||
// set _NET_WM_NAME as well for UTF-8 support in window title.
|
|
||||||
C.XSetTextProperty(dpy, win,
|
|
||||||
&C.XTextProperty{
|
|
||||||
value: (*C.uchar)(unsafe.Pointer(ctitle)),
|
|
||||||
encoding: w.atoms.utf8string,
|
|
||||||
format: 8,
|
|
||||||
nitems: C.ulong(len(title)),
|
|
||||||
},
|
|
||||||
w.atoms.wmName)
|
|
||||||
|
|
||||||
// extensions
|
// extensions
|
||||||
C.XSetWMProtocols(dpy, win, &w.atoms.evDelWindow, 1)
|
C.XSetWMProtocols(dpy, win, &w.atoms.evDelWindow, 1)
|
||||||
|
|
||||||
if o := opts.WindowMode; o != nil {
|
w.Option(opts)
|
||||||
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)
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ type Driver interface {
|
|||||||
// WriteClipboard requests a clipboard write.
|
// WriteClipboard requests a clipboard write.
|
||||||
WriteClipboard(s string)
|
WriteClipboard(s string)
|
||||||
|
|
||||||
|
// Option processes option changes.
|
||||||
|
Option(opts *Options)
|
||||||
|
|
||||||
// SetCursor updates the current cursor to name.
|
// SetCursor updates the current cursor to name.
|
||||||
SetCursor(name pointer.CursorName)
|
SetCursor(name pointer.CursorName)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user