* How to get DISPLAY of emacsclient? @ 2022-11-25 15:17 Max Nikulin 2022-11-25 16:57 ` Stefan Monnier 0 siblings, 1 reply; 19+ messages in thread From: Max Nikulin @ 2022-11-25 15:17 UTC (permalink / raw) To: emacs-devel Hi, Is it possible to get display of an emacsclient process? I mean either --display option argument or the DISPLAY environment variable namely for the client. Unfortunately the value of following expression is the DISPLAY environment of the server process emacsclient --eval '(getenv "DISPLAY")' I admit, it should work in most cases, but it is not robust: DISPLAY= emacs --daemon --display :0 causes empty string returned by `getenv'. In general, emacsclient's display is not necessary the same as the server's one. If I have got it correctly, the value is passed from client to server and there is a local "display" variable in server.el hidden from evaluated expression. The context of the question is the following. Org-capture allows to create notes in non-distracting way (by setting :immediate-finish t property of the capture template). The idea is to save text currently selected in some application (either PRIMARY or CLIPBOARD) using a global window manager shortcut invoking emacsclient --eval '(org-capture nil "x")' There is a pitfall. Emacs daemon has no frame at startup, so selection is inaccessible: emacsclient --eval "(org-get-x-clipboard 'PRIMARY)" returns nil (it is merely a convenient way to call `gui-get-selection'). A workaround is to call `server-select-display', but to do so it is necessary to know display. That is why I am asking how to obtain display of emacsclient. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-25 15:17 How to get DISPLAY of emacsclient? Max Nikulin @ 2022-11-25 16:57 ` Stefan Monnier 2022-11-26 3:36 ` Max Nikulin 0 siblings, 1 reply; 19+ messages in thread From: Stefan Monnier @ 2022-11-25 16:57 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel > Unfortunately the value of following expression is the DISPLAY environment > of the server process > > emacsclient --eval '(getenv "DISPLAY")' There are different ways which will give you different answers in different cases: - you can check the `display` parameter of the selected frame (should handle the `emacsclient --display` case). - you can check the `environment` parameter of the selected frame (probably not very useful). - You can check the `env` parameter (with `process-get`) of the proc object that represents (on Emacs's side) the emacsclient connection. For that you'll need to get access to this proc object, but I don't know offhand how to. -- Stefan ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-25 16:57 ` Stefan Monnier @ 2022-11-26 3:36 ` Max Nikulin 2022-11-26 21:33 ` chad 2022-11-27 20:36 ` Jim Porter 0 siblings, 2 replies; 19+ messages in thread From: Max Nikulin @ 2022-11-26 3:36 UTC (permalink / raw) To: emacs-devel On 25/11/2022 23:57, Stefan Monnier wrote: >> Unfortunately the value of following expression is the DISPLAY environment >> of the server process >> >> emacsclient --eval '(getenv "DISPLAY")' > > There are different ways which will give you different answers in > different cases: > > - you can check the `display` parameter of the selected frame (should > handle the `emacsclient --display` case). emacsclient --display "$DISPLAY" \ --eval "(frame-parameter (selected-frame) 'display)" may be a workaround, thank you for the idea. A caveat is that --display parameter becomes mandatory, DISPLAY environment is not enough: emacsclient --eval "(frame-parameter (selected-frame) 'display)" nil Emacs daemon may have no x frames yet at the moment of emacsclient invocation. > - you can check the `environment` parameter of the selected frame > (probably not very useful). emacsclient --display :0 \ --eval "(frame-parameter (selected-frame) 'environment)" nil > - You can check the `env` parameter (with `process-get`) of the proc > object that represents (on Emacs's side) the emacsclient connection. > For that you'll need to get access to this proc object, but I don't > know offhand how to. I am unsure that -display argument is added to the `env` parameter. I do not like the following approach since I am afraid of races. Anyway it does not work emacsclient --eval "(process-get (car server-clients) 'env)" So I have no idea how to access `proc` passed to a process filter as well. Though it does not answer to the question how to get DISPLAY, the following is at least a workaround: DISPLAY= emacs -q --daemon emacsclient --display "$DISPLAY" \ --eval "(require 'org)" \ --eval "(org-get-x-clipboard 'PRIMARY)" ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-26 3:36 ` Max Nikulin @ 2022-11-26 21:33 ` chad 2022-11-27 11:34 ` Max Nikulin 2022-11-27 20:36 ` Jim Porter 1 sibling, 1 reply; 19+ messages in thread From: chad @ 2022-11-26 21:33 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 174 bytes --] Have you considered just adding a server hook that opens a gui frame on daemon start if there is a usable display? (Apologies if you've already explored this avenue.) ~Chad [-- Attachment #2: Type: text/html, Size: 256 bytes --] ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-26 21:33 ` chad @ 2022-11-27 11:34 ` Max Nikulin 2022-11-27 13:42 ` Gregory Heytings 0 siblings, 1 reply; 19+ messages in thread From: Max Nikulin @ 2022-11-27 11:34 UTC (permalink / raw) To: emacs-devel On 27/11/2022 04:33, chad wrote: > Have you considered just adding a server hook that opens a gui frame on > daemon start if there is a usable display? The question is how to determine the display for which emacsclient is invoked. It is possible to create a hidden frame by e.g. calling `server-select-display', but it is necessary to know display. > (Apologies if you've > already explored this avenue.) Personally, I have a shell script that works for me, but I would not recommend it to others. It adds emacsclient option to create an x frame if there is no it yet. This particular question originates from an emacs-orgmode thread. It was explicitly asked that emacs should not pop up hiding currently active maximized window of another application (or emacs should disappear without additional user action, in this case its behavior should be similar to a notification window). Another participant insisted on using xsel utility and a temporary file (in a way that is not safe) because getting X selection from emacs does not work. I started current thread because Ihor Radchenko asked if `org-get-x-clipboard' could be improved and I realized that my recipe (getenv "DISPLAY") may work incorrectly in some cases. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-27 11:34 ` Max Nikulin @ 2022-11-27 13:42 ` Gregory Heytings 2022-11-27 14:23 ` Max Nikulin 0 siblings, 1 reply; 19+ messages in thread From: Gregory Heytings @ 2022-11-27 13:42 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel > > Personally, I have a shell script that works for me, but I would not > recommend it to others. It adds emacsclient option to create an x frame > if there is no it yet. > Note that emacsclient now has a '--reuse-frame' options, which creates a new frame if none exists, and uses the current Emacs frame otherwise. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-27 13:42 ` Gregory Heytings @ 2022-11-27 14:23 ` Max Nikulin 2022-11-27 14:38 ` Gregory Heytings 2022-11-28 1:19 ` Po Lu 0 siblings, 2 replies; 19+ messages in thread From: Max Nikulin @ 2022-11-27 14:23 UTC (permalink / raw) To: emacs-devel On 27/11/2022 20:42, Gregory Heytings wrote: > >> Personally, I have a shell script that works for me, but I would not >> recommend it to others. It adds emacsclient option to create an x >> frame if there is no it yet. > > Note that emacsclient now has a '--reuse-frame' options, which creates a > new frame if none exists, and uses the current Emacs frame otherwise. Thank you for adding such option. I mentioned my script mostly to show that requirements of different users are not the same. Since I have a solution working for me, I considered the priority of my issue as rather low. Moreover the emacs-help mailing list may be more suitable to discuss it. Perhaps the new option solves it. Currently I prefer to concentrate on the case of accessing X selection or getting DISPLAY without creation of visible frames. P.S. My script notifies me that emacs server is not running, so it is unlikely that I will completely remove it. It is off-topic in this thread however. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-27 14:23 ` Max Nikulin @ 2022-11-27 14:38 ` Gregory Heytings 2022-11-27 15:26 ` Max Nikulin 2022-11-28 1:19 ` Po Lu 1 sibling, 1 reply; 19+ messages in thread From: Gregory Heytings @ 2022-11-27 14:38 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel > > Currently I prefer to concentrate on the case of accessing X selection > or getting DISPLAY without creation of visible frames. > Sorry, I don't understand what "getting DISPLAY without creation of visible frames" means. Is the $DISPLAY environment variable not enough? ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-27 14:38 ` Gregory Heytings @ 2022-11-27 15:26 ` Max Nikulin 2022-11-27 16:12 ` Gregory Heytings 0 siblings, 1 reply; 19+ messages in thread From: Max Nikulin @ 2022-11-27 15:26 UTC (permalink / raw) To: emacs-devel On 27/11/2022 21:38, Gregory Heytings wrote: > >> Currently I prefer to concentrate on the case of accessing X selection >> or getting DISPLAY without creation of visible frames. > > Sorry, I don't understand what "getting DISPLAY without creation of > visible frames" means. Is the $DISPLAY environment variable not enough? I do not see a way to get the value of the DISPLAY environment variable specific to the emacsclient process. In some corner cases in may differ from emacs server display. For testing purposes the following may be used: DISPLAY= emacs --daemon A workaround I have found so far is to specify display explicitly emacsclient --display "$DISPLAY" ... ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-27 15:26 ` Max Nikulin @ 2022-11-27 16:12 ` Gregory Heytings 0 siblings, 0 replies; 19+ messages in thread From: Gregory Heytings @ 2022-11-27 16:12 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 868 bytes --] >>> Currently I prefer to concentrate on the case of accessing X selection >>> or getting DISPLAY without creation of visible frames. >> >> Sorry, I don't understand what "getting DISPLAY without creation of >> visible frames" means. Is the $DISPLAY environment variable not >> enough? > > I do not see a way to get the value of the DISPLAY environment variable > specific to the emacsclient process. > But where do you need that value, and what do you mean by "without creation of visible frames"? Not all emacsclient processes have a corresponding display, e.g. if you just do emacsclient --eval '(+ 1 1)' there is no display involved. If you create an emacsclient process with -c or -r, then in Elisp you can get the display on which the frame is displayed with (getenv "DISPLAY"), or (cdr (assq 'display (frame-parameters))). ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-27 14:23 ` Max Nikulin 2022-11-27 14:38 ` Gregory Heytings @ 2022-11-28 1:19 ` Po Lu 1 sibling, 0 replies; 19+ messages in thread From: Po Lu @ 2022-11-28 1:19 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel Max Nikulin <manikulin@gmail.com> writes: > Thank you for adding such option. I mentioned my script mostly to show > that requirements of different users are not the same. Since I have a > solution working for me, I considered the priority of my issue as > rather low. Moreover the emacs-help mailing list may be more suitable > to discuss it. Perhaps the new option solves it. > > Currently I prefer to concentrate on the case of accessing X selection > or getting DISPLAY without creation of visible frames. `x-open-connection' is your friend. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-26 3:36 ` Max Nikulin 2022-11-26 21:33 ` chad @ 2022-11-27 20:36 ` Jim Porter 2022-11-28 15:33 ` Max Nikulin 1 sibling, 1 reply; 19+ messages in thread From: Jim Porter @ 2022-11-27 20:36 UTC (permalink / raw) To: Max Nikulin, emacs-devel On 11/25/2022 7:36 PM, Max Nikulin wrote: > On 25/11/2022 23:57, Stefan Monnier wrote: >> - you can check the `display` parameter of the selected frame (should >> handle the `emacsclient --display` case). > > emacsclient --display "$DISPLAY" \ > --eval "(frame-parameter (selected-frame) 'display)" > > may be a workaround, thank you for the idea. A caveat is that --display > parameter becomes mandatory, DISPLAY environment is not enough... Looking through the emacsclient.c code, I think this is intentional, and if you want to do something like this, the above workaround is exactly what you're supposed to do: If the -c option is used (without -t) and no --display argument is provided, try $DISPLAY. Without the -c option, we used to set 'display' to $DISPLAY by default, but this changed the default behavior and is sometimes inconvenient. So we force users to use "--display $DISPLAY" if they want Emacs to connect to their current display. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-27 20:36 ` Jim Porter @ 2022-11-28 15:33 ` Max Nikulin 2022-11-28 17:15 ` Gregory Heytings 2022-11-28 18:19 ` Stefan Monnier 0 siblings, 2 replies; 19+ messages in thread From: Max Nikulin @ 2022-11-28 15:33 UTC (permalink / raw) To: emacs-devel On 28/11/2022 03:36, Jim Porter wrote: > > Looking through the emacsclient.c code, I think this is intentional, and > if you want to do something like this, the above workaround is exactly > what you're supposed to do: > > If the -c option is used (without -t) and no --display argument > is provided, try $DISPLAY. > Without the -c option, we used to set 'display' to $DISPLAY by > default, but this changed the default behavior and is sometimes > inconvenient. So we force users to use "--display $DISPLAY" if > they want Emacs to connect to their current display. Thank you, I have reread emacsclinet code and have realized that I did not expect such behavior. At first I missed that environment is sent to server only if -c option is specified and the DISPLAY environment may be ignored. I believed that display value is always received, but can not be obtained because it is assigned to a local variable. Actually it is not sent for simple eval. It is not stressed in the manual that emacsclient uses the --display option and the DISPLAY environment in a rather unusual way in comparison to other X application. I considered --display option as a way to override $DISPLAY and nothing more. emacsclient --display "$DISPLAY" --eval ... behaves as required despite it looks a bit strange. It reuses existing X connection or creates a new hidden frame. As a result X selection becomes available without additional function calls. On 28/11/2022 08:19, Po Lu wrote: > `x-open-connection' is your friend. The problem was to determine DISPLAY argument for this function. Moreover it is not enough and (gui-get-selection) return nil if just `x-open-connection' is called from emacsclient. In this sense `server-select-display' is better, but it requires DISPLAY as well. On 27/11/2022 23:12, Gregory Heytings wrote: > there is no display involved. If you create an emacsclient process with > -c or -r, then in Elisp you can get the display on which the frame is > displayed with (getenv "DISPLAY"), or (cdr (assq 'display > (frame-parameters))). I was seeking a way to avoid creation a visible frame and to call a function that does not work without X connection. So I should thank Jim again for drawing my attention why the effect of the --display option is stronger than for the DISPLAY environment. This option indirectly solves the problem. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-28 15:33 ` Max Nikulin @ 2022-11-28 17:15 ` Gregory Heytings 2022-11-28 18:19 ` Stefan Monnier 1 sibling, 0 replies; 19+ messages in thread From: Gregory Heytings @ 2022-11-28 17:15 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel > > I was seeking a way to avoid creation a visible frame and to call a > function that does not work without X connection. > > So I should thank Jim again for drawing my attention why the effect of > the --display option is stronger than for the DISPLAY environment. This > option indirectly solves the problem. > I still think this is an ill-posed problem, so here are a few additional thoughs, in case you find them useful. There are at least three cases: 1. "emacsclient --eval '(+ 1 1)'" does NOT use a display: it is evaluated in the server process. You can use '(getenv DISPLAY)' there, but it will not return any useful information, it will return the value of DISPLAY that was current when the Emacs daemon was created. 2. "emacsclient -c", which creates a frame on the display specified in the environment variable DISPLAY (if DISPLAY is unset, "emacsclient -c" is equivalent to "emacsclient -nw"). 3. "emacsclient --display <DISPLAY> -c", which creates a frame on the specified display <DISPLAY>; it is equivalent to "env DISPLAY=<DISPLAY> emacsclient -c". If you want to know the value if the environment variable DISPLAY in case 1, the best way to do that is to explicitly include "$DISPLAY" in the form you evaluate, e.g. like this: emacsclient --eval '(progn (setq display "'$DISPLAY'") (princ display))' ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-28 15:33 ` Max Nikulin 2022-11-28 17:15 ` Gregory Heytings @ 2022-11-28 18:19 ` Stefan Monnier 2022-11-29 16:23 ` Max Nikulin 1 sibling, 1 reply; 19+ messages in thread From: Stefan Monnier @ 2022-11-28 18:19 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel > Thank you, I have reread emacsclinet code and have realized that I did not > expect such behavior. At first I missed that environment is sent to server > only if -c option is specified and the DISPLAY environment may be > ignored. IIRC there is no good reason other than a historical accident (and the fact that there was no clear need for it) why the environment isn't sent in all cases. IOW, we could change it without breaking backward compatibility, AFAIK. Stefan ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-28 18:19 ` Stefan Monnier @ 2022-11-29 16:23 ` Max Nikulin 2022-11-30 0:41 ` chad 0 siblings, 1 reply; 19+ messages in thread From: Max Nikulin @ 2022-11-29 16:23 UTC (permalink / raw) To: emacs-devel On 29/11/2022 01:19, Stefan Monnier wrote: >> Thank you, I have reread emacsclinet code and have realized that I did not >> expect such behavior. At first I missed that environment is sent to server >> only if -c option is specified and the DISPLAY environment may be >> ignored. > > IIRC there is no good reason other than a historical accident (and the > fact that there was no clear need for it) why the environment isn't sent > in all cases. IOW, we could change it without breaking > backward compatibility, AFAIK. I agree with Gregory that --eval often does not need display. Certainly there are enough cases when X connection is undesired. If a frame is not ensured then display value is inaccessible from elisp code even indirectly. That is why there is a little point in sending display without exposing it through a variable. I do not mind to have such variable though. I think, the problem is that the --display option is overloaded as an interface familiar for X11 users. I have not tried other OSes, but the issue may be even more severe. I have an idea to mention "emacsclient --display ..." in the Org manual e,g, in info "(org) Protocols" and maybe in info "(org) Capture" sections https://orgmode.org/manual/Protocols.html https://orgmode.org/manual/Capture.html I do not like too verbose details related to special display values for Windows and macOS. Perhaps a boolean flag like --force-display would be easier to discover and --display DISPLAY may assume --force-display. I hope it will be easier to discover and its effect will be more clear. At least I would consider changing of documentation: info "(emacs) emacsclient Options" https://www.gnu.org/software/emacs/manual/html_node/emacs/emacsclient-Options.html "Ensure connection to the specified display (X11 or OS-specific). Notice that without this option the DISPLAY environment is used to create a new frame, but it is ignored for --eval expressions when frame-related options are omitted." instead of current > Tell Emacs to open the given files on the X display display (assuming > there is more than one X display available) I have no idea of a concise variant to replace emacsclient --help: > Visit the file in the given display On 29/11/2022 00:15, Gregory Heytings wrote: > I still think this is an ill-posed problem, so here are a few additional > thoughs, in case you find them useful. I agree that it is not really common, but I see no reason why the following cases are ill-posed: Add to user notes content of X selection when emacs is started as daemong with no frames and the user prefers to avoid distraction due to creation of a new frame. User connected to another machine through ssh (e.g. from a laptop to a desktop). In this case DISPLAY is different for the client and for the server process. (gui-get-selection) should be executed for client's DISPLAY. > 1. "emacsclient --eval '(+ 1 1)'" does NOT use a display: it is > evaluated in the server process. You can use '(getenv DISPLAY)' there, > but it will not return any useful information, it will return the value > of DISPLAY that was current when the Emacs daemon was created. Sometimes (getenv "DISPLAY") gives wrong result and I tried to highlight it in my first message and above. > 2. "emacsclient -c", which creates a frame on the display specified in > the environment variable DISPLAY (if DISPLAY is unset, "emacsclient -c" > is equivalent to "emacsclient -nw"). Terminal frame may still be associated with DISPLAY as well. The challenge is to get something useful from `gui-get-selection' (may be called by `org-capture') in the absence of a visible frame. > 3. "emacsclient --display <DISPLAY> -c", which creates a frame on the > specified display <DISPLAY>; it is equivalent to "env DISPLAY=<DISPLAY> > emacsclient -c". A subtle point is that the DISPLAY environment affects only -c while --display forces X11 connection even for --eval. > If you want to know the value if the environment variable DISPLAY in > case 1, the best way to do that is to explicitly include "$DISPLAY" in > the form you evaluate, e.g. like this: I saw that display value is sent as a part of environment and as a dedicated message. I had a hope that it is possible to access these values, so adding it once more inside --eval expression is redundant. I missed that it is sent *conditionally*. > emacsclient --eval '(progn (setq display "'$DISPLAY'") (princ display))' Unfortunately it is unsafe way to pass external values to elisp. It is unlikely, but if accidentally DISPLAY is set to some value with spaces and various shell special characters then arbitrary commands may be executed unexpectedly. I hope, some day I will summarize a discussion with Jim as a feature request to support a kind of `command-line-args-left' in expressions passed from emacsclient. Max Nikulin to emacs-orgmode. Re: Lazy load of org-protocol. Wed, 9 Feb 2022 23:46:26 +0700. https://list.orgmode.org/su0r54$f42$1@ciao.gmane.io Another pair of double quotes around $DISPLAY will deactivate shell special characters, but it is still necessary to escape double quotes and backslashes to keep elisp expression well formed. Consider DISPLAY=':0") (do-something-else) (ignore "' ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-29 16:23 ` Max Nikulin @ 2022-11-30 0:41 ` chad 2022-11-30 2:44 ` Stefan Monnier 0 siblings, 1 reply; 19+ messages in thread From: chad @ 2022-11-30 0:41 UTC (permalink / raw) To: Max Nikulin; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1963 bytes --] On Tue, Nov 29, 2022 at 1:11 PM Max Nikulin <manikulin@gmail.com> wrote: > [...] > Add to user notes content of X selection when emacs is started as > daemong with no frames and the user prefers to avoid distraction due to > creation of a new frame. > In general, you seem to assume that there's no way for emacs to create a new X11 frame object without it being immediately visible to the user. In my experience, that's only true in the limited subset of cases where the user has chosen a window manager that enforces that choice. Further, that wasn't the default when I last looked -- but that was quite some time ago, and I don't know about the current options/defaults for common X11-based display systems of today. Can anyone shed some light on this? On Tue, Nov 29, 2022 at 1:11 PM Max Nikulin <manikulin@gmail.com> wrote: > [...] User connected to another machine through ssh (e.g. from a laptop to a > desktop). In this case DISPLAY is different for the client and for the > server process. (gui-get-selection) should be executed for client's > DISPLAY. > In the past, I have regularly seen both varieties of this: where the user was logged into two machines, with an emacs server running on one, X displays on both, and wanted a new emacs frame on either one, depending on circumstances. As near as I can tell, there is no "right" choice here; the user needs to (be able to) provide input on which display to use. This is a fundamentally different case from "the user wants to use a non-graphical X11-based mechanism that emacs normally doesn't enable until emacs actually connects to a working X11 display", and I think it should be possible to get emacs to make that connection without necessarily popping up a window that the user doesn't want. I hope that helps, ~Chad P.S. Now that I've said it "out loud", I expect to learn that either the Wayland people now consider that a security hole and will disallow it, or that they already did so. [-- Attachment #2: Type: text/html, Size: 2859 bytes --] ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-30 0:41 ` chad @ 2022-11-30 2:44 ` Stefan Monnier 2022-11-30 12:47 ` Max Nikulin 0 siblings, 1 reply; 19+ messages in thread From: Stefan Monnier @ 2022-11-30 2:44 UTC (permalink / raw) To: chad; +Cc: Max Nikulin, emacs-devel chad [2022-11-29 19:41:11] wrote: > On Tue, Nov 29, 2022 at 1:11 PM Max Nikulin <manikulin@gmail.com> wrote: >> [...] >> Add to user notes content of X selection when emacs is started as >> daemong with no frames and the user prefers to avoid distraction due to >> creation of a new frame. > In general, you seem to assume that there's no way for emacs to create a > new X11 frame object without it being immediately visible to the user. In > my experience, that's only true in the limited subset of cases where the > user has chosen a window manager that enforces that choice. Further, that > wasn't the default when I last looked -- but that was quite some time ago, > and I don't know about the current options/defaults for common X11-based > display systems of today. Can anyone shed some light on this? `xclip.el` (from GNU ELPA) uses: (defun xclip--hidden-frame () (or xclip--hidden-frame (setq xclip--hidden-frame (make-frame-on-display (getenv "DISPLAY") '((visibility . nil) (user-position . t) (left . 0) (top . 0) (no-other-frame . t)))))) I haven't heard of a problem with that yet, but it probably hasn't been widely tested (and it is specific to X11). > This is a fundamentally different case from "the user wants to use a > non-graphical X11-based mechanism that emacs normally doesn't enable until > emacs actually connects to a working X11 display", and I think it should be > possible to get emacs to make that connection without necessarily popping > up a window that the user doesn't want. server.el also does something similar to xclip-mode, tho with simpler code: (defun server-select-display (display) ;; If the current frame is on `display' we're all set. ;; Similarly if we are unable to open frames on other displays, there's ;; nothing more we can do. (unless (or (not (fboundp 'make-frame-on-display)) (server--on-display-p (selected-frame) display)) ;; Otherwise, look for an existing frame there and select it. (dolist (frame (frame-list)) (when (server--on-display-p frame display) (select-frame frame))) ;; If there's no frame on that display yet, create and select one. (unless (server--on-display-p (selected-frame) display) (let* ((buffer (generate-new-buffer " *server-dummy*")) (frame (make-frame-on-display display ;; Make it display (and remember) some dummy buffer, so ;; we can detect later if the frame is in use or not. `((server-dummy-buffer . ,buffer) ;; This frame may be deleted later (see ;; server-unselect-display) so we want it to be as ;; unobtrusive as possible. (visibility . nil))))) (select-frame frame) (set-window-buffer (selected-window) buffer) frame)))) This code has been used a lot more widely, but in many/most cases we end up making that frame visible soon after, so there might be cases where it is not 100% unobtrusive but users don't notice it. Stefan ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: How to get DISPLAY of emacsclient? 2022-11-30 2:44 ` Stefan Monnier @ 2022-11-30 12:47 ` Max Nikulin 0 siblings, 0 replies; 19+ messages in thread From: Max Nikulin @ 2022-11-30 12:47 UTC (permalink / raw) To: emacs-devel To avoid misunderstanding, emacsclient --display "$DISPLAY" --eval ... solves the problem (on Linux). For me, reasons to continue the discussion is that Stefan considered changes in Emacs code and that some suggestions was oversimplified. On 30/11/2022 09:44, Stefan Monnier wrote: > chad [2022-11-29 19:41:11] wrote: >> On Tue, Nov 29, 2022 at 1:11 PM Max Nikulin wrote: >>> [...] >>> Add to user notes content of X selection when emacs is started as >>> daemong with no frames and the user prefers to avoid distraction due to >>> creation of a new frame. >> In general, you seem to assume that there's no way for emacs to create a >> new X11 frame object without it being immediately visible to the user. In >> my experience, that's only true in the limited subset of cases where the >> user has chosen a window manager that enforces that choice. No, I did not assume it, it the starting message I mentioned `server-select-display' that creates a hidden frame. I have not tested various window managers though, I hope it just works. I was aware of info "(elisp) Visibility of Frames" https://www.gnu.org/software/emacs/manual/html_node/elisp/Visibility-of-Frames.html The problem is how to determine proper display from an expression passed to emacsclient --eval. > `xclip.el` (from GNU ELPA) uses: Interesting, I had an impression that the main reason to invoke xclip/pbcopy/etc from Emacs is an alternative MIME type (selection target), e.g. text/html in the case of https://github.com/jkitchin/ox-clip > (setq xclip--hidden-frame > (make-frame-on-display (getenv "DISPLAY") It is appropriate for Emacs compiled with no X11 support, but in general, when overridden by --display, it may cause connection to a wrong display. Another case DISPLAY= emacs --daemon --display :0 > '((visibility . nil) > (user-position . t) > (left . 0) > (top . 0) > (no-other-frame . t)))))) I consider it as another argument that `x-open-connection' is not enough to get selection and a frame is required. > I haven't heard of a problem with that yet, but it probably hasn't been > widely tested (and it is specific to X11). I would say that, accordingly to the code, it is specific to (eq xclip-method 'emacs), not to X11. >> This is a fundamentally different case from "the user wants to use a >> non-graphical X11-based mechanism that emacs normally doesn't enable until >> emacs actually connects to a working X11 display" I never expected getting selection without opening of an X connection. I think an X11 window (frame in Emacs parlance) is not strictly necessary, but I am quite happy with a hidden frame. > server.el also does something similar to xclip-mode, tho with simpler > code: Despite server.el sets less frame properties, it skips creation a frame if another one already exists on the specified display. That is why I would not call its code simpler. > This code has been used a lot more widely, but in many/most cases we end > up making that frame visible soon after, so there might be cases where > it is not 100% unobtrusive but users don't notice it. I have not noticed any problem with this code (besides tightly encapsulated value of display), but I have tried only Linux. chad [2022-11-29 19:41:11] wrote: > On Tue, Nov 29, 2022 at 1:11 PM Max Nikulin wrote: > >> User connected to another machine through ssh (e.g. from a laptop to a >> desktop). In this case DISPLAY is different for the client and for the >> server process. (gui-get-selection) should be executed for client's DISPLAY. > > In the past, I have regularly seen both varieties of this: where the > user was logged into two machines, with an emacs server running on one, > X displays on both, and wanted a new emacs frame on either one, > depending on circumstances. As near as I can tell, there is no "right" > choice here; the user needs to (be able to) provide input on which > display to use. I agree with you in general but in the case of accessing selected text it is almost certainly display where emacsclient is called. Such choice is a reason that I did not consider the --display option at first. Usually its purpose is solely to override "$DISPLAY" value without additional effects. ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2022-11-30 12:47 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-11-25 15:17 How to get DISPLAY of emacsclient? Max Nikulin 2022-11-25 16:57 ` Stefan Monnier 2022-11-26 3:36 ` Max Nikulin 2022-11-26 21:33 ` chad 2022-11-27 11:34 ` Max Nikulin 2022-11-27 13:42 ` Gregory Heytings 2022-11-27 14:23 ` Max Nikulin 2022-11-27 14:38 ` Gregory Heytings 2022-11-27 15:26 ` Max Nikulin 2022-11-27 16:12 ` Gregory Heytings 2022-11-28 1:19 ` Po Lu 2022-11-27 20:36 ` Jim Porter 2022-11-28 15:33 ` Max Nikulin 2022-11-28 17:15 ` Gregory Heytings 2022-11-28 18:19 ` Stefan Monnier 2022-11-29 16:23 ` Max Nikulin 2022-11-30 0:41 ` chad 2022-11-30 2:44 ` Stefan Monnier 2022-11-30 12:47 ` Max Nikulin
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).