app: add Window.Raise to bring a window to the front

Fixes gio#252

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
This commit is contained in:
Pierre Curto
2021-09-08 22:02:26 +02:00
committed by Elias Naur
parent c5d4e01e3d
commit 2f66ed1dc8
10 changed files with 61 additions and 0 deletions
+1
View File
@@ -113,6 +113,7 @@ const (
SWP_NOOWNERZORDER = 0x0200
SWP_NOSIZE = 0x0001
SWP_NOZORDER = 0x0004
SWP_SHOWWINDOW = 0x0040
USER_TIMER_MINIMUM = 0x0000000A
+3
View File
@@ -141,6 +141,9 @@ type driver interface {
// SetCursor updates the current cursor to name.
SetCursor(name pointer.CursorName)
// Raise the window at the top.
Raise()
// Close the window.
Close()
// Wakeup wakes up the event loop and sends a WakeupEvent.
+2
View File
@@ -822,6 +822,8 @@ func (w *window) Config() Config {
return w.config
}
func (w *window) Raise() {}
func (w *window) SetCursor(name pointer.CursorName) {
runInJVM(javaVM(), func(env *C.JNIEnv) {
setCursor(env, w.view, name)
+2
View File
@@ -275,6 +275,8 @@ func (w *window) Config() Config {
return w.config
}
func (w *window) Raise() {}
func (w *window) SetAnimating(anim bool) {
v := w.view
if v == 0 {
+2
View File
@@ -534,6 +534,8 @@ func (w *window) Config() Config {
return w.config
}
func (w *window) Raise() {}
func (w *window) SetCursor(name pointer.CursorName) {
style := w.cnv.Get("style")
style.Set("cursor", string(name))
+10
View File
@@ -127,6 +127,12 @@ static CFTypeRef layerForView(CFTypeRef viewRef) {
NSView *view = (__bridge NSView *)viewRef;
return (__bridge CFTypeRef)view.layer;
}
static void raiseWindow(CFTypeRef windowRef) {
NSWindow* window = (__bridge NSWindow *)windowRef;
[window makeKeyAndOrderFront:nil];
}
*/
import "C"
@@ -268,6 +274,10 @@ func (w *window) SetAnimating(anim bool) {
}
}
func (w *window) Raise() {
C.raiseWindow(w.window)
}
func (w *window) runOnMain(f func()) {
runOnMain(func() {
// Make sure the view is still valid. The window might've been closed
+2
View File
@@ -927,6 +927,8 @@ func (w *window) Config() Config {
return w.config
}
func (w *window) Raise() {}
func (w *window) SetCursor(name pointer.CursorName) {
if name == pointer.CursorNone {
C.wl_pointer_set_cursor(w.disp.seat.pointer, w.serial, nil, 0, 0)
+6
View File
@@ -663,6 +663,12 @@ func (w *window) Close() {
windows.PostMessage(w.hwnd, windows.WM_CLOSE, 0, 0)
}
func (w *window) Raise() {
windows.SetForegroundWindow(w.hwnd)
windows.SetWindowPos(w.hwnd, windows.HWND_TOPMOST, 0, 0, 0, 0,
windows.SWP_NOMOVE|windows.SWP_NOSIZE|windows.SWP_SHOWWINDOW)
}
func convertKeyCode(code uintptr) (string, bool) {
if '0' <= code && code <= '9' || 'A' <= code && code <= 'Z' {
return string(rune(code)), true
+23
View File
@@ -79,6 +79,8 @@ type x11Window struct {
wmState C.Atom
// "_NET_WM_STATE_FULLSCREEN"
wmStateFullscreen C.Atom
// "_NET_ACTIVE_WINDOW"
wmActiveWindow C.Atom
}
stage system.Stage
metric unit.Metric
@@ -165,6 +167,26 @@ func (w *x11Window) Config() Config {
return w.config
}
func (w *x11Window) Raise() {
var xev C.XEvent
ev := (*C.XClientMessageEvent)(unsafe.Pointer(&xev))
*ev = C.XClientMessageEvent{
_type: C.ClientMessage,
display: w.x,
window: w.xw,
message_type: w.atoms.wmActiveWindow,
format: 32,
}
C.XSendEvent(
w.x,
C.XDefaultRootWindow(w.x), // MUST be the root window
C.False,
C.SubstructureNotifyMask|C.SubstructureRedirectMask,
&xev,
)
C.XMapRaised(w.display(), w.xw)
}
func (w *x11Window) SetCursor(name pointer.CursorName) {
switch name {
case pointer.CursorNone:
@@ -680,6 +702,7 @@ func newX11Window(gioWin *callbacks, options []Option) error {
w.atoms.wmName = w.atom("_NET_WM_NAME", false)
w.atoms.wmState = w.atom("_NET_WM_STATE", false)
w.atoms.wmStateFullscreen = w.atom("_NET_WM_STATE_FULLSCREEN", false)
w.atoms.wmActiveWindow = w.atom("_NET_ACTIVE_WINDOW", false)
// extensions
C.XSetWMProtocols(dpy, win, &w.atoms.evDelWindow, 1)
+10
View File
@@ -604,6 +604,16 @@ func (w *Window) updateCursor() {
}
}
// Raise requests that the platform bring this window to the top of all open windows.
// Some platforms do not allow this except under certain circumstances, such as when
// a window from the same application already has focus. If the platform does not
// support it, this method will do nothing.
func (w *Window) Raise() {
w.driverDefer(func(d driver) {
d.Raise()
})
}
func (q *queue) Events(k event.Tag) []event.Event {
return q.q.Events(k)
}