emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: x-selection-exists-p vs x-get-selection


From: Drew Adams
Subject: RE: x-selection-exists-p vs x-get-selection
Date: Sun, 4 May 2008 01:33:10 -0700

> > I don't understand `x-selection-exists-p'. I select some 
> > text with meta mouse clicks or drags, to create a secondary
> > selection. (x-get-selection 'SECONDARY)
> > returns that secondary-selection text, as I would expect.
> > 
> > But (x-selection-exists-p 'SECONDARY) returns nil - I 
> > expected t. The doc string says: "Whether there is an owner
> > for the given X Selection." I am on Windows,
> > with `x-select-enable-clipboard' = t, if that is important.
> > 
> > Is there a bug here? If not can someone please enlighten me?
> > 
> > How should I understand `x-selection-exists-p'? It is used, 
> > for instance, in menu-bar.el, to determine whether to enable
> > some selection menus, such as Paste.
> 
> These functions make sense only on X window systems.

I see. But they are used on all platforms. I see `x-selection-exists-p' used in
menu-bar.el as an :enable check, for instance, as I mentioned. And if
`x-selection-exists-p' is not the way to test for a given selection (e.g.
SECONDARY) on Windows, then what is?

> Their functionality on Windows is tuned to make their callers DTRT, but
> that's all; there's no underlying theory that would make sense on
> Windows besides that.  There are no ``selections'' on Windows, and no
> ``owners'' of selections.  If you want to understand these functions'
> semantics on X, read some X manual.

BTW, the Emacs documentation calls it "secondary selection", even if "there are
no ``selections'' on Windows". The entire section in the Emacs manual about
Secondary Selection is written as if it is only for the X Window System, but the
same or similar behavior exists for Emacs on Windows. Is it TRT that the doc is
written this way? Shouldn't there be, at a minimum, a sentence saying that this
works for other than just X-Window Emacs? Is this just a case of Emacs showing
its legacy?

> If you have specific situations where the code using them misbehaves
> on Windows, please describe those situations.

How to know if it "misbehaves" on Windows, since you've said that there is no
prescribed behavior for Windows? ;-) They are meaningless on Windows.
Nevertheless, they are used.

Actually, what appears to happen is this - this is the code for the standard
Paste menu item:

(define-key menu-bar-edit-menu [paste]
  '(menu-item "Paste" yank :enable
     (and ;; Emacs compiled --without-x doesn't have
      ;; x-selection-exists-p.
      (fboundp 'x-selection-exists-p)
      (x-selection-exists-p)
      (not buffer-read-only))
     :help "Paste (yank) text most recently cut/copied"))

[BTW, in spite of the comment (unless I'm misunderstanding it), (fboundp
'x-selection-exists-p) returns t on Windows.] 

However, on Windows, w32-win.el calls `menu-bar-enable-clipboard' (at top-level,
when it is loaded - not as a minor mode or something), which substitutes
`clipboard-yank' for `yank' as [paste]. And that uses this enablement instead:

(put 'clipboard-yank 'menu-enable
     '(and (or (and (fboundp 'x-selection-exists-p)
                    (x-selection-exists-p))
               (x-selection-exists-p 'CLIPBOARD))
           (not buffer-read-only)))

That seems a roundabout and fragile way to do things. It's fragile because it
means that function `menu-bar-enable-clipboard' must deal explicitly with every
command that might ever need to be treated this way.

If a user wants to add a Paste Secondary menu item, then s?he must add a
`clipboard-yank-secondary' command and also do, for that function, what
`menu-bar-enable-clipboard' does for the others, on all (and on only) the right
platforms.

That seems like an ugly hack. I'm not sure what a better approach would be, but
what about just using a global variable for such enablement, instead of calling
`menu-bar-enable-clipboard'? The `clipboard-*' functions themselves use
`x-select-enable-clipboard'. Couldn't that be used directly in the :enable
clause, and then just have a single set of commands?

IOW, just use `yank', instead of `clipboard-yank', but with an :enable value
that uses `x-select-enable-clipboard':

(define-key menu-bar-edit-menu [paste]
  '(menu-item "Paste" yank
     :enable (and (or (and (fboundp 'x-selection-exists-p)
                           (x-selection-exists-p))
                      (and x-select-enable-clipboard
                           (x-selection-exists-p 'CLIPBOARD)))
                  (not buffer-read-only))
     :help "Paste (yank) text most recently cut/copied"))

(Or perhaps the third `and' should come before the second?)

That way, too, users or code could turn such menu items on and off using the
variable, whereas now they can only turn them on (not off), using function
`menu-bar-enable-clipboard'. Dunno if that would be useful, but it is less
clunky.

I imagine there is a good reason for doing things the way they are done, but
it's not clear to me. Perhaps it has something to do with this comment about
pure space in `menu-bar-enable-clipboard'?

;; We can't use constant list structure here because it becomes pure,
;; and because it gets modified with cache data.

I'm ignorant about the pure space and cache data treatment. Could you explain
this, if it is in fact what is behind the complicated way things are done for
these menu items? If it is not the reason, then what is? I'm not so much arguing
that the code should be different as I am trying to understand why it is the way
it is.

If the code stays the way it is, then how should a user add a Paste Secondary
item with proper enablement?

One workaround, at least for Windows, would be to just use (x-get-selection
'SECONDARY) instead of (x-selection-exists-p 'SECONDARY) - that seems to work,
for whatever reason - it returns non-nil on Windows only when there is a
secondary. That might not be kosher, but what's the alternative?







reply via email to

[Prev in Thread] Current Thread [Next in Thread]