ArcticaProject / nx-libs

nx-libs
Other
120 stars 39 forks source link

nxagent window in desktop mode can not be closed #435

Closed mviereck closed 5 years ago

mviereck commented 7 years ago

I'm using nxagent as a standalone nested X server. If any applications are running in nxagent, I can not close nxagent desktop window. I get this error message:

NXTransDialog: WARNING! Couldn't start '/usr/NX/bin/nxclient'. Error is 2 'No such file or directory'.
Warning: Couldn't start '/usr/NX/bin/nxclient'. Error is 2 'No such file or directory'.

As nxclient does not exist, I'm using a workaround. I can specify a fake nxclient with environment variable NX_CLIENT. nxagent sends this cli options:

--dialog yesnosuspend --caption NX --message Press the disconnect button to disconnect the running session.
You will be able to resume the session at later time. Press the
terminate button to exit the session and close all the running
programs. --parent 9869 --display :1448

Switch --parent provides the process id of nxagent. Parsing the output, I can kill nxagent:

#! /bin/bash
# helper script to terminate nxagent. 
# nxagent runs program stored in NX_CLIENT if desktop window close button is pressed.
# (real nxclient does not exist)
echo "NXclient: $@" >> '$Xinitlogfile'
parsed=$(getopt --options="" --longoptions="parent:,display:,dialog:,caption:,message:" -- "$@")
eval set -- $parsed
while [ -n "$1" ] ; do
  case "$1" in
    --dialog) dialog=$2 && shift ;;
    --display|--caption|--message|--window) shift ;;
    --parent) pid=$2 && shift ;;
    --) ;;
  esac
  shift
done
case $dialog in
  yesnosuspend)  kill $pid  ;;
esac
uli42 commented 7 years ago

So what is this ticket about? Do you want to contribute? Or do you want to extend nxagent to skip nxclient handling if nxclient cannot be found?

Please note that Mike#1 is already working on replacing the NX_CLIENT stuff completely, see here: #387

BTW: neatx offers a nxdialog tool, that may be used here: https://github.com/wk8/neatx/blob/master/lib/app/nxdialog.py

BTW2, here's the help of the original nxclient, in case you want to extend your code (however, the --parent option is missing here, so it might not be the most current version):

NXCLIENT - Version 3.5.0-7

Usage: nxclient [OPTIONS]

--config FILENAME | DIRECTORY

  Run nxclient reading global configuration settings from the file
  FILENAME. FILENAME can either be an absolute or relative path. In
  the latter case the path is searched for starting from the current
  directory. If no FILENAME is found in the current directory then
  FILENAME is searched for starting from the user's home directory.
  If DIRECTORY is given and a file 'client.cfg' is found in that di-
  rectory, then the global configuration settings are read from this
  file. The filename does not need to end with the string '.cfg'.

--dialog TYPE [--caption TITLE] [--message MESSAGE] [--local]
              [--window ID] [--class {info|warning|error}]
              [--allowmultiple]

  Show a dialog box. The option must be followed by a 'type' parame-
  ter which specifies the type of dialog.

  TYPE can be either:

  yesno
  ok
  error
  panic
  quit
  pulldown

  The user should specify a caption and a message to be shown. The
  option --local can be used to specify the proxy mode.

  The 'pulldown' dialog is a special tiny window that is embedded in
  the window specified in the --window parameter, to allow the user
  to suspend or terminate a session running in seamless mode.

  The --class option specifies the class of the message. When no class
  is specified the message will be assumed to be of the class 'Info'. 

  The --allowmultiple option specifies the possibility to launch more
  than one dialog with the same message.

--monitor [--owner USERNAME]

  Run the "NX Shadow Monitor" application for tracking users when
  connected either to the local display or to the master session.
  This application allows to send a message to the selected user
  and to disconnect him/her.

--help

  Display this help and exit.

--printer PRINTER_NAME

  Show a dialog box with the list of CUPS printer drivers found on
  the server.

  It may return:

  - Exit code 0 and the name of the driver selected by the user.
    The name of the driver is written on the STDIN.

  - Exit code 1 in the case of an error. The error message is
    printed on the STDERR.

  - Exit code 2 and no error message, if the user chose to abort
    the operation.

--session FILENAME

  Run a session reading the configuration settings from FILENAME.

--plugin FILENAME

  Run the client in the special 'plugin' mode, reading the configu-
  ration settings from FILENAME.

--version

  Output version information and exit.

--wizard

  Guide the user through the steps required to configure a session.

--admin

  Run the "NX Session Administrator" interface. The interface can be
  used to perform administrative tasks on the NX sessions run by the
  user, for example viewing the logs, printing the statistics or
  closing the session.

--display

  Specify the X11 display where the client must connect. The option
  is only useful on platforms where the client is using the X-Window
  protocol for the display.

All options can be given with a single dash (as in 'nxclient -help').
This is for backward compatibility with older versions. Note that the
single-dash format is deprecated and will be likely removed in future
versions.
sunweaver commented 7 years ago

Hi,

On Mi 19 Apr 2017 03:51:15 CEST, mviereck wrote:

I'm using nxagent as a standalone nested X server. If any applications are running in nxagent, I can not close nxagent
desktop window. I get this error message:

NXTransDialog: WARNING! Couldn't start '/usr/NX/bin/nxclient'. Error  
is 2 'No such file or directory'.
Warning: Couldn't start '/usr/NX/bin/nxclient'. Error is 2 'No such  
file or directory'.

As nxclient does not exist, I'm using a workaround. I can specify a
fake nxclient with environment variable NX_CLIENT. nxagent sends
this cli options:

--dialog yesnosuspend --caption NX --message Press the disconnect  
button to disconnect the running session.
You will be able to resume the session at later time. Press the
terminate button to exit the session and close all the running
programs. --parent 9869 --display :1448

Switch --parent provides the process id of nxagent. Parsing the
output, I can kill nxagent:

#! /bin/bash
# helper script to terminate nxagent.
# nxagent runs program stored in NX_CLIENT if window close button is pressed.
# (real nxclient does not exist)
eval set -- $(getopt --longoptions  
"parent:,display:,dialog:,caption:,message:" -- "$@")
while [ -n "$1" ] ; do
  case "$1" in
    --dialog|--display|--caption|--message) shift ;;
    --parent) kill $2 && shift ;;
    --) ;;
  esac
  shift
done

I have already started playing with that, but am unsure what approach
to finally follow:

https://github.com/ArcticaProject/nx-libs/pull/387 https://github.com/ArcticaProject/nxagent-callbacks-dispatcher/blob/master/nxagent-callbacks-dispatcher

The current approach has various disadvantageous...

A much better approach would be:

One thing, I'd like to do is have a simple script that gets called via
the NX_CLIENT variable. This is for legacy. The "script" should
immitate what nxclient used to do. Unfortunately, this is not 100%
doable with zenity. The idea is writing a little nxagent-dialogs
application in GTK or Qt or what that pops up dialog boxes and menus.

The new approach could be to write real dispatcher e.g. utilizing
DBus. The nxagent calls a sub-command that triggers some DBus event
and inside the running desktop session an app is waiting for such
events and reacts on them.

However, the most common use case is probably that nxagent is handled
by some framework (like X2Go, TheQVD, Arctica). If that is the case,
then those callbacks should be handed over to the framework and be
processed there.

Looking forward to an interesting discussion on what approach might be
interesting for you. Maybe you have some time available that you can
give to this(?).

Greets, Mike --

DAS-NETZWERKTEAM mike gabriel, herweg 7, 24357 fleckeby mobile: +49 (1520) 1976 148 landline: +49 (4354) 8390 139

GnuPG Fingerprint: 9BFB AEE8 6C0A A5FF BF22 0782 9AF4 6B30 2577 1B31 mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de

mviereck commented 7 years ago

Hello!

So what is this ticket about? Do you want to contribute? Or do you want to extend nxagent to skip nxclient handling if nxclient cannot be found?

It is some sort of contribution; I had this issue, found a workaround and want to share it, if some else looks here for the same reason. (Though, I had to update the script in the meantime because there were two bugs (missing --options=""for getopt and missing check for "yesnosuspend" as nxagent randomly calls nxclient with another message).

Maybe you have some time available that you can give to this(?).

I thought a bit about this, and yes, I would like to write a fully working nxclient. So far, I'm a bit experienced in bash scripting, but not in GTK or QT. At a first glance, I think I could handle python. However, I want to be able to create GUIs, and nxclient would be a nice project to start with. Python as a simple script language with GTK and QT API's seems to be appropriate. GUI's with bash are very limited, the most flexible tool I found is kaptain. I use it for x11docker. (x11docker uses nxagent beneath xpra and Xephyr). Unfortunately, kaptain is no longer maintained and was already removed from debian stretch. A great loss, as there is no similar project with this functionality.

BTW: neatx offers a nxdialog tool, that may be used here: https://github.com/wk8/neatx/blob/master/lib/app/nxdialog.py

This seems to be a nearly complete solution, why not adapting it?

The current approach has various disadvantageous...

  • messages are hard-coded in nxagent
    • messages are English only
  • textual messages should be localizable

nxclient could show messages based on --dialog switch, ignoring the content of --message. Is there already a multilingual concept for nxagent? A custom solution for nxclient should not be too hard. Multilingual variations could be stored in the script.

  • messages are evoked by calling an external application One thing, I'd like to do is have a simple script that gets called via the NX_CLIENT variable. This is for legacy.

In this case, it will stay an external script. It could be temporary created at runtime by nxagent to avoid having a second hard-depending permanent executeable.

The new approach could be to write real dispatcher e.g. utilizing DBus.

Not sure about that, but looking in a possible future with nxagent in Wayland, it may be better to avoid dbus as it is not supported by Wayland.

However, the most common use case is probably that nxagent is handled by some framework (like X2Go, TheQVD, Arctica). If that is the case, then those callbacks should be handed over to the framework and be processed there.

As I'm using nxagent as a standalone server so far, I'm not familar with all use cases. Is nxclient itself is called only by nxagent?

Greets, Martin

uli42 commented 7 years ago

neatx code ist quite old so we must check if it is still working. Also the license should be checked. And we should check if it offers a the menu feature.

I would prefere a single standalone binary instead of a python program that requires some modules but I am fine if we adapt nxdialog.

Regarding dbus: AFAIK Xorg does aslo not support dbus (neither does nxagent). This is something the desktop environment uses, not the underlying display server. Correct me if I am wrong.

Not sure if nxclient is only called from nxagent. nxagent runs this program inside its own session as a normal X client. But the calling code is in the nxcomp part that is also used by nxproxy.

uli42 commented 7 years ago

BTW: I have stumbled across nxcl which contains some dbus stuff: https://packages.debian.org/de/source/stretch/nxcl

Ionic commented 7 years ago

Yes, of course, neither X.Org nor Wayland use dbus explicitly, but applications do.

Within Wayland, applications can communicate via a built-in IPC mechanism, rendering dbus useless for its sole purpose. Wayland-applications thus don't use it.

uli42 commented 7 years ago

@mviereck: have you already done something here?

uli42 commented 7 years ago

I have just noticed that opennx includes an nxclient, and apparently it is GPL licensed. So we could probably simply use that.

nxclient -h
Usage: nxclient [-h] [--verbose] [--autologin] [--autoresume] [--killerrors] [--admin] [--cacert <str>] [--caption <str>] [--style <str>] [--dialog <str>] [--display <str>] [--exportres <str>] [--local] [--message <str>] [--parent <num>] [--session <str>] [--window <num>] [--trace <str>] [--wizard]
  -h, --help            show this help message
  --verbose             generate verbose log messages
  --autologin           Automatically login to the specified session.
  --autoresume          Automatically resume/takeover a session with the same name.
  --killerrors          Automatically destroy error dialogs at termination.
  --admin               Start the session administration tool.
  --cacert=<str>        Specify alternate CA cert for fetching configuration via https.
  --caption=<str>       Specify window title for dialog mode.
  --style=<str>         Specify dialog style for dialog mode.
  --dialog=<str>        Run in dialog mode.
  --display=<str>       Compatibility option for dialog mode (ignored).
  --exportres=<str>     Export builtin GUI resources to zip file and exit.
  --local               Dialog mode proxy.
  --message=<str>       Specify message for dialog mode.
  --parent=<num>        Specify parent PID for dialog mode.
  --session=<str>       Run a session importing configuration settings from FILENAME.
  --window=<num>        Specify window-ID for dialog mode.
  --trace=<str>         Specify wxWidgets trace mask.
  --wizard              Guide the user through the steps to configure a session.

Supported trace tags: AsyncProcess LibOpenSC LibUSB LogDialog LoginDialog MyDynlib MyIPC MySession MyWizard MyXmlConfig PulseAudio ResumeDialog SessionAdmin SessionList SessionProperties ShareProperties WinShare opennxApp
uli42 commented 5 years ago

I have tested the nxdialog.py from neatx and it is working great with nxagent in rootless mode. We should integrate that, but we'd have to remove some (most?) of additional code of neatx to make it a standalone solution.

uli42 commented 5 years ago

So far we these possibilties:

uli42 commented 5 years ago

There's now a PR for our own version of neatx's nxdialog: #767

sunweaver commented 5 years ago

nxdialog will be shipped with 3.5.99.19. Thus closing this one.