2021-01-18 11:50:03 +13:00
|
|
|
package desktop
|
|
|
|
|
|
|
|
import (
|
2021-08-30 03:09:13 +12:00
|
|
|
"errors"
|
2021-01-18 11:50:03 +13:00
|
|
|
"os/exec"
|
2022-01-30 13:23:05 +13:00
|
|
|
|
2022-03-20 23:27:41 +13:00
|
|
|
"gitlab.com/demodesk/neko/server/internal/desktop/xorg"
|
2021-01-18 11:50:03 +13:00
|
|
|
)
|
|
|
|
|
2021-09-03 07:37:24 +12:00
|
|
|
// name of the window that is being controlled
|
|
|
|
const fileChooserDialogName = "Open File"
|
|
|
|
|
|
|
|
// short sleep value between fake user interactions
|
|
|
|
const fileChooserDialogShortSleep = "0.2"
|
|
|
|
|
|
|
|
// long sleep value between fake user interactions
|
|
|
|
const fileChooserDialogLongSleep = "0.4"
|
2021-01-21 11:51:53 +13:00
|
|
|
|
2021-01-18 11:50:03 +13:00
|
|
|
func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
2021-01-21 11:51:53 +13:00
|
|
|
// TODO: Use native API.
|
2021-01-26 08:23:40 +13:00
|
|
|
err1 := exec.Command(
|
2021-01-18 11:50:03 +13:00
|
|
|
"xdotool",
|
2021-09-03 07:37:24 +12:00
|
|
|
"search", "--name", fileChooserDialogName, "windowfocus",
|
|
|
|
"sleep", fileChooserDialogShortSleep,
|
2021-02-15 02:40:17 +13:00
|
|
|
"key", "--clearmodifiers", "ctrl+l",
|
|
|
|
"type", "--args", "1", uri+"//",
|
2021-09-03 07:37:24 +12:00
|
|
|
"sleep", fileChooserDialogShortSleep,
|
2021-02-15 02:40:17 +13:00
|
|
|
"key", "Delete", // remove autocomplete results
|
2021-09-03 07:37:24 +12:00
|
|
|
"sleep", fileChooserDialogShortSleep,
|
2021-02-15 02:40:17 +13:00
|
|
|
"key", "Return",
|
2021-09-03 07:37:24 +12:00
|
|
|
"sleep", fileChooserDialogLongSleep,
|
2021-02-15 02:40:17 +13:00
|
|
|
"key", "Down",
|
|
|
|
"key", "--clearmodifiers", "ctrl+a",
|
|
|
|
"key", "Return",
|
2021-09-03 07:37:24 +12:00
|
|
|
"sleep", fileChooserDialogLongSleep,
|
2021-01-26 08:23:40 +13:00
|
|
|
).Run()
|
|
|
|
|
|
|
|
if err1 != nil {
|
|
|
|
return err1
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Use native API.
|
|
|
|
err2 := exec.Command(
|
|
|
|
"xdotool",
|
2021-09-03 07:37:24 +12:00
|
|
|
"search", "--name", fileChooserDialogName,
|
2021-01-21 11:51:53 +13:00
|
|
|
).Run()
|
2021-01-18 11:50:03 +13:00
|
|
|
|
2021-01-26 08:23:40 +13:00
|
|
|
// if last command didn't return error, consider dialog as still open
|
|
|
|
if err2 == nil {
|
2021-08-30 03:09:13 +12:00
|
|
|
return errors.New("unable to select files in dialog")
|
2021-01-26 08:23:40 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2021-01-18 11:50:03 +13:00
|
|
|
}
|
|
|
|
|
2021-01-20 09:01:31 +13:00
|
|
|
func (manager *DesktopManagerCtx) CloseFileChooserDialog() {
|
2021-01-18 22:34:33 +13:00
|
|
|
for i := 0; i < 5; i++ {
|
2021-01-21 11:51:53 +13:00
|
|
|
mu.Lock()
|
|
|
|
|
|
|
|
manager.logger.Debug().Msg("attempting to close file chooser dialog")
|
|
|
|
|
|
|
|
// TODO: Use native API.
|
|
|
|
err := exec.Command(
|
|
|
|
"xdotool",
|
2021-09-03 07:37:24 +12:00
|
|
|
"search", "--name", fileChooserDialogName, "windowfocus",
|
2021-01-21 11:51:53 +13:00
|
|
|
).Run()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
mu.Unlock()
|
|
|
|
manager.logger.Info().Msg("file chooser dialog is closed")
|
2021-01-20 09:01:31 +13:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-01-21 11:51:53 +13:00
|
|
|
// custom press Alt + F4
|
|
|
|
// because xdotool is failing to send proper Alt+F4
|
|
|
|
|
2021-01-26 05:36:43 +13:00
|
|
|
//nolint
|
2022-01-30 13:23:05 +13:00
|
|
|
manager.KeyPress(xorg.XK_Alt_L, xorg.XK_F4)
|
2021-01-21 11:51:53 +13:00
|
|
|
|
2021-01-18 22:34:33 +13:00
|
|
|
mu.Unlock()
|
|
|
|
}
|
2021-01-18 11:50:03 +13:00
|
|
|
}
|
|
|
|
|
2021-01-20 09:01:31 +13:00
|
|
|
func (manager *DesktopManagerCtx) IsFileChooserDialogOpened() bool {
|
2021-01-18 11:50:03 +13:00
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
|
|
|
|
2021-01-21 11:51:53 +13:00
|
|
|
// TODO: Use native API.
|
|
|
|
err := exec.Command(
|
2021-01-18 11:50:03 +13:00
|
|
|
"xdotool",
|
2021-09-03 07:37:24 +12:00
|
|
|
"search", "--name", fileChooserDialogName,
|
2021-01-21 11:51:53 +13:00
|
|
|
).Run()
|
2021-01-18 11:50:03 +13:00
|
|
|
|
|
|
|
return err == nil
|
|
|
|
}
|