mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
file chooser dialog events implementation.
This commit is contained in:
@ -60,11 +60,11 @@ void XEventLoop(char *name) {
|
||||
|
||||
char *name;
|
||||
XFetchName(display, window, &name);
|
||||
|
||||
|
||||
XTextProperty role;
|
||||
XGetTextProperty(display, window, &role, WM_WINDOW_ROLE);
|
||||
|
||||
goXEventWindowCreated(window, name, role.value);
|
||||
|
||||
goXEventCreateNotify(window, name, role.value);
|
||||
XFree(name);
|
||||
continue;
|
||||
}
|
||||
@ -75,15 +75,64 @@ void XEventLoop(char *name) {
|
||||
|
||||
char *name;
|
||||
XFetchName(display, window, &name);
|
||||
|
||||
|
||||
XTextProperty role;
|
||||
XGetTextProperty(display, window, &role, WM_WINDOW_ROLE);
|
||||
|
||||
goXEventWindowConfigured(window, name, role.value);
|
||||
|
||||
goXEventConfigureNotify(display, window, name, role.value);
|
||||
XFree(name);
|
||||
continue;
|
||||
}
|
||||
|
||||
// UnmapNotify
|
||||
if (event.type == UnmapNotify) {
|
||||
Window window = event.xunmap.window;
|
||||
goXEventUnmapNotify(window);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
void XFileChooserHide(Display *display, Window window) {
|
||||
Window root = RootWindow(display, 0);
|
||||
|
||||
// The WM_TRANSIENT_FOR property is defined by the [ICCCM] for managed windows.
|
||||
// This specification extends the use of the property to override-redirect windows.
|
||||
// If an override-redirect is a pop-up on behalf of another window, then the Client
|
||||
// SHOULD set WM_TRANSIENT_FOR on the override-redirect to this other window.
|
||||
//
|
||||
// As an example, a Client should set WM_TRANSIENT_FOR on dropdown menus to the
|
||||
// toplevel application window that contains the menubar.
|
||||
|
||||
// Remove WM_TRANSIENT_FOR
|
||||
Atom WM_TRANSIENT_FOR = XInternAtom(display, "WM_TRANSIENT_FOR", 0);
|
||||
XDeleteProperty(display, window, WM_TRANSIENT_FOR);
|
||||
|
||||
// Add _NET_WM_STATE_BELOW
|
||||
XClientMessageEvent clientMessageEvent;
|
||||
memset(&clientMessageEvent, 0, sizeof(clientMessageEvent));
|
||||
|
||||
// window = the respective client window
|
||||
// message_type = _NET_WM_STATE
|
||||
// format = 32
|
||||
// data.l[0] = the action, as listed below
|
||||
// _NET_WM_STATE_REMOVE 0 // remove/unset property
|
||||
// _NET_WM_STATE_ADD 1 // add/set property
|
||||
// _NET_WM_STATE_TOGGLE 2 // toggle property
|
||||
// data.l[1] = first property to alter
|
||||
// data.l[2] = second property to alter
|
||||
// data.l[3] = source indication
|
||||
// other data.l[] elements = 0
|
||||
|
||||
clientMessageEvent.type = ClientMessage;
|
||||
clientMessageEvent.window = window;
|
||||
clientMessageEvent.message_type = XInternAtom(display, "_NET_WM_STATE", 0);
|
||||
clientMessageEvent.format = 32;
|
||||
clientMessageEvent.data.l[0] = 1;
|
||||
clientMessageEvent.data.l[1] = XInternAtom(display, "_NET_WM_STATE_BELOW", 0);
|
||||
clientMessageEvent.data.l[3] = 1;
|
||||
|
||||
XSendEvent(display, root, 0, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&clientMessageEvent);
|
||||
}
|
||||
|
@ -8,12 +8,14 @@ package xevent
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/kataras/go-events"
|
||||
)
|
||||
|
||||
var emmiter events.EventEmmiter
|
||||
var file_chooser_dialog_window uint32 = 0
|
||||
|
||||
func init() {
|
||||
emmiter = events.New()
|
||||
@ -38,15 +40,15 @@ func OnClipboardUpdated(listener func()) {
|
||||
})
|
||||
}
|
||||
|
||||
func OnWindowCreated(listener func(window uint32, name string, role string)) {
|
||||
emmiter.On("window-created", func(payload ...interface{}) {
|
||||
listener(payload[0].(uint32), payload[1].(string), payload[2].(string))
|
||||
func OnFileChooserDialogOpened(listener func()) {
|
||||
emmiter.On("file-chooser-dialog-opened", func(payload ...interface{}) {
|
||||
listener()
|
||||
})
|
||||
}
|
||||
|
||||
func OnWindowConfigured(listener func(window uint32, name string, role string)) {
|
||||
emmiter.On("window-configured", func(payload ...interface{}) {
|
||||
listener(payload[0].(uint32), payload[1].(string), payload[2].(string))
|
||||
func OnFileChooserDialogClosed(listener func()) {
|
||||
emmiter.On("file-chooser-dialog-closed", func(payload ...interface{}) {
|
||||
listener()
|
||||
})
|
||||
}
|
||||
|
||||
@ -66,14 +68,38 @@ func goXEventClipboardUpdated() {
|
||||
emmiter.Emit("clipboard-updated")
|
||||
}
|
||||
|
||||
//export goXEventWindowCreated
|
||||
func goXEventWindowCreated(window C.Window, name *C.char, role *C.char) {
|
||||
emmiter.Emit("window-created", uint32(window), C.GoString(name), C.GoString(role))
|
||||
//export goXEventCreateNotify
|
||||
func goXEventCreateNotify(window C.Window, nameUnsafe *C.char, roleUnsafe *C.char) {
|
||||
role := C.GoString(roleUnsafe)
|
||||
if role != "GtkFileChooserDialog" {
|
||||
return
|
||||
}
|
||||
|
||||
file_chooser_dialog_window = uint32(window)
|
||||
emmiter.Emit("file-chooser-dialog-opened")
|
||||
}
|
||||
|
||||
//export goXEventWindowConfigured
|
||||
func goXEventWindowConfigured(window C.Window, name *C.char, role *C.char) {
|
||||
emmiter.Emit("window-configured", uint32(window), C.GoString(name), C.GoString(role))
|
||||
//export goXEventConfigureNotify
|
||||
func goXEventConfigureNotify(display *C.Display, window C.Window, nameUnsafe *C.char, roleUnsafe *C.char) {
|
||||
role := C.GoString(roleUnsafe)
|
||||
if role != "GtkFileChooserDialog" {
|
||||
return
|
||||
}
|
||||
|
||||
C.XFileChooserHide(display, window)
|
||||
|
||||
// Because first dialog is not put properly to background
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
C.XFileChooserHide(display, window)
|
||||
}
|
||||
|
||||
//export goXEventUnmapNotify
|
||||
func goXEventUnmapNotify(window C.Window) {
|
||||
if uint32(window) != file_chooser_dialog_window {
|
||||
return
|
||||
}
|
||||
|
||||
emmiter.Emit("file-chooser-dialog-closed")
|
||||
}
|
||||
|
||||
//export goXEventError
|
||||
|
@ -5,13 +5,17 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern void goXEventCursorChanged(XFixesCursorNotifyEvent event);
|
||||
extern void goXEventClipboardUpdated();
|
||||
extern void goXEventWindowCreated(Window window, char *name, char *role);
|
||||
extern void goXEventWindowConfigured(Window window, char *name, char *role);
|
||||
extern void goXEventCreateNotify(Window window, char *name, char *role);
|
||||
extern void goXEventConfigureNotify(Display *display, Window window, char *name, char *role);
|
||||
extern void goXEventUnmapNotify(Window window);
|
||||
extern void goXEventError(XErrorEvent *event, char *message);
|
||||
extern int goXEventActive();
|
||||
|
||||
static int XEventError(Display *display, XErrorEvent *event);
|
||||
void XEventLoop(char *display);
|
||||
|
||||
void XFileChooserHide(Display *display, Window window);
|
||||
|
Reference in New Issue
Block a user