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:
parent
22d31e871c
commit
d4e0287eb5
@ -97,7 +97,7 @@ func (h *RoomHandler) uploadDialogPost(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
defer r.MultipartForm.RemoveAll()
|
defer r.MultipartForm.RemoveAll()
|
||||||
|
|
||||||
if !h.desktop.IsFileChooserDialogOpen() {
|
if !h.desktop.IsFileChooserDialogOpened() {
|
||||||
utils.HttpBadRequest(w, "Open file chooser dialog first.")
|
utils.HttpBadRequest(w, "Open file chooser dialog first.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -149,15 +149,11 @@ func (h *RoomHandler) uploadDialogPost(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *RoomHandler) uploadDialogClose(w http.ResponseWriter, r *http.Request) {
|
func (h *RoomHandler) uploadDialogClose(w http.ResponseWriter, r *http.Request) {
|
||||||
if !h.desktop.IsFileChooserDialogOpen() {
|
if !h.desktop.IsFileChooserDialogOpened() {
|
||||||
utils.HttpBadRequest(w, "File chooser dialog is not open.")
|
utils.HttpBadRequest(w, "File chooser dialog is not open.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !h.desktop.CloseFileChooserDialog() {
|
h.desktop.CloseFileChooserDialog()
|
||||||
utils.HttpInternalServerError(w, "Unable to close file chooser dialog.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.HttpSuccess(w)
|
utils.HttpSuccess(w)
|
||||||
}
|
}
|
||||||
|
@ -1,52 +1,9 @@
|
|||||||
package desktop
|
package desktop
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
file_chooser_dialog_open = false
|
|
||||||
)
|
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) fileChooserDialogStart() {
|
|
||||||
if manager.IsFileChooserDialogOpen() {
|
|
||||||
manager.CloseFileChooserDialog()
|
|
||||||
}
|
|
||||||
|
|
||||||
manager.OnWindowCreated(func(window uint32, name string, role string) {
|
|
||||||
if role != "GtkFileChooserDialog" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Implement, call event.
|
|
||||||
file_chooser_dialog_open = true
|
|
||||||
|
|
||||||
manager.logger.Debug().
|
|
||||||
Uint32("window", window).
|
|
||||||
Msg("GtkFileChooserDialog has been opened")
|
|
||||||
})
|
|
||||||
|
|
||||||
manager.OnWindowConfigured(func(window uint32, name string, role string) {
|
|
||||||
if role != "GtkFileChooserDialog" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
go func(){
|
|
||||||
// TOOD: Refactor.
|
|
||||||
manager.PutWindowBelow(window)
|
|
||||||
|
|
||||||
// Because first dialog is not put properly to background
|
|
||||||
time.Sleep(500 * time.Millisecond)
|
|
||||||
manager.PutWindowBelow(window)
|
|
||||||
}()
|
|
||||||
|
|
||||||
manager.logger.Debug().
|
|
||||||
Uint32("window", window).
|
|
||||||
Msg("GtkFileChooserDialog has been put below main window")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
@ -54,7 +11,7 @@ func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
|||||||
// TOOD: Use native API.
|
// TOOD: Use native API.
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"xdotool",
|
"xdotool",
|
||||||
"search", "--name", "Open", "windowfocus",
|
"search", "--name", "Open File", "windowfocus",
|
||||||
"sleep", "0.2",
|
"sleep", "0.2",
|
||||||
"key", "--clearmodifiers", "ctrl+l",
|
"key", "--clearmodifiers", "ctrl+l",
|
||||||
"type", "--args", "1", uri + "//",
|
"type", "--args", "1", uri + "//",
|
||||||
@ -66,43 +23,36 @@ func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
|||||||
"sleep", "0.3",
|
"sleep", "0.3",
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Implement, call event.
|
|
||||||
file_chooser_dialog_open = false
|
|
||||||
|
|
||||||
_, err := cmd.Output()
|
_, err := cmd.Output()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) CloseFileChooserDialog() bool {
|
func (manager *DesktopManagerCtx) CloseFileChooserDialog() {
|
||||||
for i := 0; i < 5; i++ {
|
for i := 0; i < 5; i++ {
|
||||||
|
if !manager.IsFileChooserDialogOpened() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// TOOD: Use native API.
|
// TOOD: Use native API.
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
exec.Command(
|
exec.Command(
|
||||||
"xdotool",
|
"xdotool",
|
||||||
"search", "--name", "Open", "windowfocus",
|
"search", "--name", "Open File", "windowfocus",
|
||||||
"sleep", "0.2",
|
"sleep", "0.2",
|
||||||
"key", "--clearmodifiers", "alt+F4",
|
"key", "--clearmodifiers", "alt+F4",
|
||||||
).Output()
|
).Output()
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
|
|
||||||
if !manager.IsFileChooserDialogOpen() {
|
|
||||||
// TODO: Implement, call event.
|
|
||||||
file_chooser_dialog_open = false
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
func (manager *DesktopManagerCtx) IsFileChooserDialogOpened() bool {
|
||||||
}
|
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) IsFileChooserDialogOpen() bool {
|
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
|
||||||
// TOOD: Use native API.
|
// TOOD: Use native API.
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
"xdotool",
|
"xdotool",
|
||||||
"search", "--name", "Open", "windowfocus",
|
"search", "--name", "Open File",
|
||||||
)
|
)
|
||||||
|
|
||||||
_, err := cmd.Output()
|
_, err := cmd.Output()
|
||||||
|
@ -53,7 +53,8 @@ func (manager *DesktopManagerCtx) Start() {
|
|||||||
|
|
||||||
go xevent.EventLoop(manager.display)
|
go xevent.EventLoop(manager.display)
|
||||||
|
|
||||||
go manager.fileChooserDialogStart()
|
// In case it was opened
|
||||||
|
go manager.CloseFileChooserDialog()
|
||||||
|
|
||||||
manager.OnEventError(func(error_code uint8, message string, request_code uint8, minor_code uint8) {
|
manager.OnEventError(func(error_code uint8, message string, request_code uint8, minor_code uint8) {
|
||||||
manager.logger.Warn().
|
manager.logger.Warn().
|
||||||
|
@ -12,12 +12,12 @@ func (manager *DesktopManagerCtx) OnClipboardUpdated(listener func()) {
|
|||||||
xevent.OnClipboardUpdated(listener)
|
xevent.OnClipboardUpdated(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) OnWindowCreated(listener func(window uint32, name string, role string)) {
|
func (manager *DesktopManagerCtx) OnFileChooserDialogOpened(listener func()) {
|
||||||
xevent.OnWindowCreated(listener)
|
xevent.OnFileChooserDialogOpened(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) OnWindowConfigured(listener func(window uint32, name string, role string)) {
|
func (manager *DesktopManagerCtx) OnFileChooserDialogClosed(listener func()) {
|
||||||
xevent.OnWindowConfigured(listener)
|
xevent.OnFileChooserDialogClosed(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8)) {
|
func (manager *DesktopManagerCtx) OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8)) {
|
||||||
|
@ -64,7 +64,7 @@ void XEventLoop(char *name) {
|
|||||||
XTextProperty role;
|
XTextProperty role;
|
||||||
XGetTextProperty(display, window, &role, WM_WINDOW_ROLE);
|
XGetTextProperty(display, window, &role, WM_WINDOW_ROLE);
|
||||||
|
|
||||||
goXEventWindowCreated(window, name, role.value);
|
goXEventCreateNotify(window, name, role.value);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -79,11 +79,60 @@ void XEventLoop(char *name) {
|
|||||||
XTextProperty role;
|
XTextProperty role;
|
||||||
XGetTextProperty(display, window, &role, WM_WINDOW_ROLE);
|
XGetTextProperty(display, window, &role, WM_WINDOW_ROLE);
|
||||||
|
|
||||||
goXEventWindowConfigured(window, name, role.value);
|
goXEventConfigureNotify(display, window, name, role.value);
|
||||||
XFree(name);
|
XFree(name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmapNotify
|
||||||
|
if (event.type == UnmapNotify) {
|
||||||
|
Window window = event.xunmap.window;
|
||||||
|
goXEventUnmapNotify(window);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XCloseDisplay(display);
|
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 "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/kataras/go-events"
|
"github.com/kataras/go-events"
|
||||||
)
|
)
|
||||||
|
|
||||||
var emmiter events.EventEmmiter
|
var emmiter events.EventEmmiter
|
||||||
|
var file_chooser_dialog_window uint32 = 0
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
emmiter = events.New()
|
emmiter = events.New()
|
||||||
@ -38,15 +40,15 @@ func OnClipboardUpdated(listener func()) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnWindowCreated(listener func(window uint32, name string, role string)) {
|
func OnFileChooserDialogOpened(listener func()) {
|
||||||
emmiter.On("window-created", func(payload ...interface{}) {
|
emmiter.On("file-chooser-dialog-opened", func(payload ...interface{}) {
|
||||||
listener(payload[0].(uint32), payload[1].(string), payload[2].(string))
|
listener()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func OnWindowConfigured(listener func(window uint32, name string, role string)) {
|
func OnFileChooserDialogClosed(listener func()) {
|
||||||
emmiter.On("window-configured", func(payload ...interface{}) {
|
emmiter.On("file-chooser-dialog-closed", func(payload ...interface{}) {
|
||||||
listener(payload[0].(uint32), payload[1].(string), payload[2].(string))
|
listener()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,14 +68,38 @@ func goXEventClipboardUpdated() {
|
|||||||
emmiter.Emit("clipboard-updated")
|
emmiter.Emit("clipboard-updated")
|
||||||
}
|
}
|
||||||
|
|
||||||
//export goXEventWindowCreated
|
//export goXEventCreateNotify
|
||||||
func goXEventWindowCreated(window C.Window, name *C.char, role *C.char) {
|
func goXEventCreateNotify(window C.Window, nameUnsafe *C.char, roleUnsafe *C.char) {
|
||||||
emmiter.Emit("window-created", uint32(window), C.GoString(name), C.GoString(role))
|
role := C.GoString(roleUnsafe)
|
||||||
|
if role != "GtkFileChooserDialog" {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//export goXEventWindowConfigured
|
file_chooser_dialog_window = uint32(window)
|
||||||
func goXEventWindowConfigured(window C.Window, name *C.char, role *C.char) {
|
emmiter.Emit("file-chooser-dialog-opened")
|
||||||
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
|
//export goXEventError
|
||||||
|
@ -5,13 +5,17 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
extern void goXEventCursorChanged(XFixesCursorNotifyEvent event);
|
extern void goXEventCursorChanged(XFixesCursorNotifyEvent event);
|
||||||
extern void goXEventClipboardUpdated();
|
extern void goXEventClipboardUpdated();
|
||||||
extern void goXEventWindowCreated(Window window, char *name, char *role);
|
extern void goXEventCreateNotify(Window window, char *name, char *role);
|
||||||
extern void goXEventWindowConfigured(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 void goXEventError(XErrorEvent *event, char *message);
|
||||||
extern int goXEventActive();
|
extern int goXEventActive();
|
||||||
|
|
||||||
static int XEventError(Display *display, XErrorEvent *event);
|
static int XEventError(Display *display, XErrorEvent *event);
|
||||||
void XEventLoop(char *display);
|
void XEventLoop(char *display);
|
||||||
|
|
||||||
|
void XFileChooserHide(Display *display, Window window);
|
||||||
|
@ -113,7 +113,3 @@ func (manager *DesktopManagerCtx) GetKeyboardModifiers() types.KeyboardModifiers
|
|||||||
func (manager *DesktopManagerCtx) GetCursorImage() *types.CursorImage {
|
func (manager *DesktopManagerCtx) GetCursorImage() *types.CursorImage {
|
||||||
return xorg.GetCursorImage()
|
return xorg.GetCursorImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) PutWindowBelow(window uint32) {
|
|
||||||
xorg.PutWindowBelow(window)
|
|
||||||
}
|
|
||||||
|
@ -136,46 +136,3 @@ XFixesCursorImage *XGetCursorImage(void) {
|
|||||||
Display *display = getXDisplay();
|
Display *display = getXDisplay();
|
||||||
return XFixesGetCursorImage(display);
|
return XFixesGetCursorImage(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XPutWindowBelow(Window window) {
|
|
||||||
Display *display = getXDisplay();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
@ -244,13 +244,6 @@ func GetCursorImage() *types.CursorImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PutWindowBelow(window uint32) {
|
|
||||||
mu.Lock()
|
|
||||||
defer mu.Unlock()
|
|
||||||
|
|
||||||
C.XPutWindowBelow(C.Window(window))
|
|
||||||
}
|
|
||||||
|
|
||||||
//export goCreateScreenSize
|
//export goCreateScreenSize
|
||||||
func goCreateScreenSize(index C.int, width C.int, height C.int, mwidth C.int, mheight C.int) {
|
func goCreateScreenSize(index C.int, width C.int, height C.int, mwidth C.int, mheight C.int) {
|
||||||
ScreenConfigurations[int(index)] = types.ScreenConfiguration{
|
ScreenConfigurations[int(index)] = types.ScreenConfiguration{
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <X11/extensions/XTest.h>
|
#include <X11/extensions/XTest.h>
|
||||||
#include <X11/extensions/Xfixes.h>
|
#include <X11/extensions/Xfixes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
extern void goCreateScreenSize(int index, int width, int height, int mwidth, int mheight);
|
extern void goCreateScreenSize(int index, int width, int height, int mwidth, int mheight);
|
||||||
extern void goSetScreenRates(int index, int rate_index, short rate);
|
extern void goSetScreenRates(int index, int rate_index, short rate);
|
||||||
@ -28,5 +27,3 @@ short XGetScreenRate();
|
|||||||
void XSetKeyboardModifier(int mod, int on);
|
void XSetKeyboardModifier(int mod, int on);
|
||||||
char XGetKeyboardModifiers();
|
char XGetKeyboardModifiers();
|
||||||
XFixesCursorImage *XGetCursorImage(void);
|
XFixesCursorImage *XGetCursorImage(void);
|
||||||
|
|
||||||
void XPutWindowBelow(Window window);
|
|
||||||
|
@ -57,8 +57,8 @@ type DesktopManager interface {
|
|||||||
// xevent
|
// xevent
|
||||||
OnCursorChanged(listener func(serial uint64))
|
OnCursorChanged(listener func(serial uint64))
|
||||||
OnClipboardUpdated(listener func())
|
OnClipboardUpdated(listener func())
|
||||||
OnWindowCreated(listener func(window uint32, name string, role string))
|
OnFileChooserDialogOpened(listener func())
|
||||||
OnWindowConfigured(listener func(window uint32, name string, role string))
|
OnFileChooserDialogClosed(listener func())
|
||||||
OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8))
|
OnEventError(listener func(error_code uint8, message string, request_code uint8, minor_code uint8))
|
||||||
|
|
||||||
// clipboard
|
// clipboard
|
||||||
@ -70,6 +70,6 @@ type DesktopManager interface {
|
|||||||
|
|
||||||
// filechooser
|
// filechooser
|
||||||
HandleFileChooserDialog(uri string) error
|
HandleFileChooserDialog(uri string) error
|
||||||
CloseFileChooserDialog() bool
|
CloseFileChooserDialog()
|
||||||
IsFileChooserDialogOpen() bool
|
IsFileChooserDialogOpened() bool
|
||||||
}
|
}
|
||||||
|
@ -134,13 +134,16 @@ func (ws *WebSocketManagerCtx) Start() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ws.desktop.OnWindowCreated(func(window uint32, name string, role string) {
|
ws.desktop.OnFileChooserDialogOpened(func() {
|
||||||
// TODO: Implement.
|
// TODO: Implement.
|
||||||
ws.logger.Info().
|
ws.logger.Info().
|
||||||
Uint32("window", window).
|
Msg("FileChooserDialog opened")
|
||||||
Str("name", name).
|
})
|
||||||
Str("role", role).
|
|
||||||
Msg("created new window")
|
ws.desktop.OnFileChooserDialogClosed(func() {
|
||||||
|
// TODO: Implement.
|
||||||
|
ws.logger.Info().
|
||||||
|
Msg("FileChooserDialog closed")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user