libglui / glui

GLUI is a GLUT-based C++ user interface library which provides controls such as buttons, checkboxes, radio buttons, and spinners to OpenGL applications. It is window-system independent, using GLUT or FreeGLUT.
Other
196 stars 81 forks source link

Push/Pull-request pending: "Copy & Paste" #62

Closed m-7761 closed 5 years ago

m-7761 commented 7 years ago

I've added Windows copy/paste and am investigating X11 in the coming days before committing the new code/changes.

I would not announce it this way. Except for some hotkey binding issues, which might be discussed now...

First, the EditText control has a lot of Control-key combos that I think would be alien to Windows users. My sense is that being cross-platform, GLUI should identify the smallest possible number of functional hotkeys and use those. This is not something that should be up to the client/user. It should be up to the end-user, or nobody.

If hotkey conventions are up to the end-user, it seems like it should use a system environment variable to configure them. If not, GLUI should keep things very simple.

On Windows simple means: Ctrl+A is select all, and Ctrl+X,C,V is clipboard business. And off the top of my head that's it. To add more is Ctrl+Z,Y for undo/redo, and many advanced users like Ctrl+Shift+Z for redo.

GLUI currently collides with Ctrl+A. So this patch/commit changes it for _WIN32 builds. I think the Linux world has adopted XCV for clipboard (in addition to middle-mouse and maybe Ctrl+Insert for accessing the separate X11 PRIMARY "selection." Its CLIPBOARD selection is used for Windows like semantics.)

I also removed destructive actions for Windows users. Because "undo" is not supported. I think it would better to agree on a small selection of system specific hotkeys that can be combined if they do not overlap. But that using Shift and the usual Home/End/Delete keys and so on should suffice for operations that can use them. Select-All being the exception.

GLUI shouldn't cater to non-cross-platform applications. But there is a fuzzy line between that and basic functionality. And I think by using a minimal subset the remaining hotkeys can be reserved for accessibility concerns.

Non-Windows users can provide some feedback.

I changed handling of "Esc" to happen inside the top-level container. On Windows Esc returns control to the parent window, so it can decide how to handle it, and I'm not even sure that it deactivates the control it originates in. But I've made GLUI deactivate the control and forward the input (Esc) to active window/subwindow's GLUT window...

I think if you "escape" there needs to be somewhere to escape to, and simply deactivating the active control is not a useful action. It just confuses the end-user. I took this opportunity (in my application) to hide the input box so it doesn't occlude the main viewport and return control to the non-UI application.

Below is the interface. There are changes to the EditText key handler, but I'm not sure, there is also TextBox, which maybe someone can work on before applying the patch I present. I'm not sure I want to do a mock up of a multiline edit box right this instant. But I think copy/paste is an important enough feature that I won't sit on it. I need it for URL input, which is primarily not done by typing out longhand.

`/****/ / / / Copy/Paste GLUI Class / / / /****/

class GLUIAPI GLUI_Clipboard_Object { public:

GLUI_Clipboard_Object(const char *name);

/**
 * Typically @c name is CLIPBOARD or PRIMARY.
 * PRIMARY is available only on X11 systems, and
 * should be set whenever a selection is finalized.
 */
const GLUI_String name;

/**
 * This is analogous to copying to the clipboard.
 */
void set_text(const char *sel, size_t len); 

/**
 * This is analogous to pasting from the clipboard, or
 * that is, getting the text on the clipboard to paste.
 */
bool get_text(GLUI_String &container);

};

/**

GLUI_Selection is the PRIMARY selection. Its name is PRIMARY. This is implemented in a new GLUI_clipboard.cpp file. And in the key handlers.

nigels-com commented 7 years ago

Are you familar enough with git to selectively get changes onto a branch for review? It's better for review purposes to have smaller change sets to work with, understand and discuss.

nigels-com commented 7 years ago

Concerning Ctrl-A.

Indeed on Windows this is the conventional binding for select-all.

And on Mac, it would be Command-A for select-all.

But GLUI GLUI_EditText::key_handler is implementing readline bindings which are conventional at a shell command line.

My general sense of this conflict over bindings is that readline ought to be opt-in, since it's less general purpose than the Windows/KDE/Gnome bindings.

m-7761 commented 7 years ago

I only know Git from a read-only perspective. I much prefer Subversion, but I am going to learn the ins-and-outs of Git (for GLUI.) Just have patience. (I do understand the differing philosophy and architectures, because I've had to decide before which to use to host things.)

My expectation is I will do a "push" or something (a commit) to the "fork" I checked out, and then do a "pull-request" and then I will leave the details to whoever integrates such requests. They can treat it as a patch. Or as they like. When I really go into development mode it will probably be easier for everyone if I can take a more administrative roll and directly commit changes; but if that sounds scary or is not even possible (under Git/Github) don't worry about it. I just have a feeling I'm going to be available to GLUI for an order of magnitude more hours than anyone else, and it will become a kind of bottleneck. (As long as it doesn't cause me too much time lost and things get done I'll be happy either way.)

I know the bindings come from somewhere, they just seem esoteric. And there's an awful lot of them for a default.

Does GLUT convert Command-A into Unix C^ sequences? Does it understand Command key if not?

Going by your link I feel like GLUI should only support A,X,C,V,Z,Y and Y conflicts with the paste function for "readline" and its for command-lines and not window-manager use, so I think maintaining it in a textbox context is hard to justify...

I looked into this and could not find mention of Ctrl+Y for pasting (from Wikipedia) even though it probably does; what seems to be the view is Shift+Insert pastes, and Ctrl+Insert copies; but also just selecting text automatically copies it, so Ctrl+Insert should DO NOTHING if applications are doing things according to the X11 mandates. So I'm pretty confused here. I assume that in addition the mouse-cursor must be hovered over the insertion point, or a more conservative view might be that merely positioning the cursor does not discard the PRIMARY buffer (but forming a selection replaces its contents.)

The more I've thought about PRIMARY the more I've realized that it should probably only be filled by explicit mouse-dragging selections. It's supposed to use the middle-button to paste, and keyboard selection would have to detect repeating keys, and Tab key navigation would activate controls and so select their content (also good for highlighting them) and so means that using keyboard along to copy from one control to another using PRIMARY is impossible.

If Shift+Insert is supported it should be only because it's convention and to emulate the middle-button. Perhaps people bind extra buttons on their mouse to this key combination (because the middle button is often a wheel which can be clumsy to press down and browsers tend to use it for other things than pasting.)

^EDITED: On second thought, I suppose if you are tabbing to controls and mouse-pasting into another window or even another control it could conceivably be useful, but this really seems like a stretch...

I actually have no idea if Shift+Insert is emulating a mouse click at (x,y) or should (or must) use a cursor positioned by the arrow keys. I will have to figure it out to implement PRIMARY. (Hopefully discovering the "display" is not a problem. I will find out before days end.)

nigels-com commented 7 years ago

maintaining readline bindings in a textbox context is hard to justify

I disagree. They will of course seem esoteric to most Windows users. But they're just as natural in the Unix world as Ctrl-X,C,V are on Windows. Also consider, on a Mac I have the luxury of Command-X,C,V and Ctrl-A, etc, with no collision whatsoever. Disabling readline bindings (compile-time or run-time y default) on Windows (in preference for cut-paste) makes sense, we can probably agree.

m-7761 commented 7 years ago

For the record I've been having a not so good time with Cygwin, trying to get to the bottom of issues with the device-contexts getting lost when the windows are hidden or iconified. The glutHideWindow one is much more pernicious because it seems to invalidate the GLX context's handle. (edited: Technically its WGL, being Windows land.) If it's a permanent fixture of Cygwin it would mean either abandoning it or freeglut would need to recreate the context when it comes out of hiding (which used to be a perfectly natural thing that happens with Direct3D contexts. But since the system has become dependent on compositors those things tend not to happen, and I'm not sure why they'd happen to a GLX implementation on Windows 10.)

I've sunk many hours into that while also trying to understand CMake better (I have a deep dislike of its design.)

There were other bugs in GLUI that I fixed. They will show up in the eventual commit (push?) The rather simple file-browser control had used double-clicks. I'm not sure that that's ever a good idea. But it was set to 300ms which was probably way too little time for Cygwin/X, and while the time could be extended, I did what I normally do with double-clicks and made it so that clicking a selected item amounts to double-clicking (there's never a reason to select something twice.)

Windows lists have both a focus and a selection, so that unless they are fused it's not necessary to have an item selected. I think it works better when the focus is a lighter color than the selection than when it's a dotted outline. It's hard to tell when the control is activated if it doesn't light up.

I am slightly interested in learning about Xlib, but it seems that the X protocol is stuck on OpenGL 1.4 and probably will be forever; so I'm a little more interested in Wayland I guess, and because of the trouble with Cygwin (maybe it's not evolving either) I'm beginning to wonder about MinGw?

I've always been a little fascinated with the idea of remote graphics. But honestly with COLLADA the "skin" and "morphing" animations generally need to be implemented on the CPU unless "effects" incorporate them into their GPU programs. The thought of the CPU animation being sent over a network at 60fps (vertex buffers) makes me more than a little pale. I guess to implement that there'd need to be a remote animator sitting on the server's end. As it gets more complicated the mystique wears off. Maybe the X people eventually regretted what they did...

Speaking of that, the X systray icon of Cygwin's has an option to turn the PRIMARY clipboard on and off, which I guess is the easiest way possible for users to opt into that. Some of the Linux world applications want Ctrl+Shift to use copy and paste. I gotta say that seems like over kill for such a regular activity.

P.S. Whether I stay with Cygwin to redeem its X server or not, there is enough working that I can work on the copy/paste function. That may well be my last dalliance with Xlib.

nigels-com commented 7 years ago

Yeah, I really don't think Cygwin GLX/X11 is going to be all that useful for GLUI development and testing. It's certainly not well supported by FreeGLUT and isn't likely to be more than software-rendered.

m-7761 commented 7 years ago

It's not software-rendered. It's usable, but end-users would not be well served by it. I think only developers use Cygwin anyway. It's a way to develop POSIX software if your day job is Windows. It beats virtual machines in my book, but I have made a note to look into alternatives. I'm not sure what remains of Cygnus or what their goal ever was with Cygwin, but it's served me well over the years.

I think most X implementations nowadays just pass the rendered image to the server. Presumably there's an optimized pathway to a compositor if the client and server are on the same machine. If the server must render it would be limited to very early OpenGL remote procedure calls.

I hope that the alternatives to X basically emulate its protocol, or Xlib implementations can work with those servers at least to do things like manage the clipboard. It seems like if not there would be a lot of old software that would suddenly be unusable; and anyway, I don't relish implementing more than Xlib copy-paste. (Mac-OS would be good to support, but I think someone else can contribute it. I'm in no position to in any case.)

nigels-com commented 7 years ago

Further information concerning Cygwin GLX

I don't recall glxinfo reporting other than Mesa, but it's been quite some time since I looked. Perhaps things have changed.

m-7761 commented 7 years ago

(Thanks. I've had that link open in a tab--that happens to be right beside this tab. My glxinfo actually reports three vendors: SGI, Mesa, and Intel. I think SGI is like the software layer of the original X server. Mesa probably implements GLX, etc. And Intel--although last--is the manufacturer, and I assume that it is used by default. The fact that the errors generated are WGL means that a hardware pathway is used. Via Windows proxy.)

Well I did just read something as little while ago as 2008 that said hardware-acceleration was not enabled by the Cygwin/X server. It seems to me that there's still a lot of progress happening with Cygwin, and also that MinGW is not really an alternative to it (I'm sure I've understood this in the past only to forget it) although I intend to take a look at Xming since it sounds like it could a more self-contained X experience on Windows. (I assume there is a client development aspect to it.)

Mesa has become a kind clearing house for 3-D on Linux I believe. Even the DRM stuff which is full-hardware is grouped under its working group on Linux.

From what I can gather Wayland is not compatible with X11 copy-paste-wise, and the Wikipedia article even says it has no copy-paste element, but that is contradicted by many online materials.

This article ( https://wiki.gnome.org/Initiatives/Wayland/PrimarySelection ) gives a rationale for not supporting the "Primary Selection" model. What solutions exist to sync Wayland with X11 seem to only do so for the "clipboard" and their availability seems scarce, unless there's a glut of old blogs online from pre-interoperability days.

I think in general a GLUI should err on the side of minimalism. This is part of the reason I'm hesitant about the "readline" discussion, because I think it sows division and is just a very expanded hotkey set. It seems like something that would be better facilitated under the rubric of an "extension" than something part of a GLUI identity. Especially because the window-environment world is approaching some kind of standard-ese, which is a good thing.

The article says the auto-copy behavior picks up on passwords and private information and so on, and I guess it's a problem because I read elsewhere that X11's behavior was to broadcast the selection-change to every client (which just seems as extravagant and pointless as the selection-design--only clipboard viewers require such broadcasts) but while I don't think that's such a problem for a GLUI, the "PRIMARY" selection is in many ways complicated to facilitate and is largely ancillary, although not difficult to facilitate if available; and so I would group it under the "extension" heading too. (If only because it may or may not be there, so it's only for users who have a reason to expect it to be there for them.)

I don't know if there is life in the X server. It seems like projects like AIGLX are innovating and presumably overcoming the limits of GLX. The original effort to accelerate Cygwin was titled AIGLX; it seemed to disappear one day, but now it's basically using a wrapper around WGL provided by the Mesa package. I can't tell if anyone is thinking about improving it (or Cygwin) or not, but I don't see anything else that's like Cygwin, so I hope so, and I think Cygwin's singularity is reason enough to hold out hopes for it.

P.S. I reported my experience to the freeglut mailing list (I'd actually unsubscribed) and a Chris contacted me. I thought it was via the mailing list (I know it was in the digest once) but I noticed today that my replies were going to what seemed like a private gmail address that may indicate not. (I hope the freeglut team takes pride in their software and proactively address such a broad issue. My interactions with free-software developers tend to leave me very unimpressed; and I think that there is a process by which good representatives are turned away by bad developers who ultimately strangulate free-software by their roosting on top of it. They will say that they do this in their free-time, but I tend to think that's a strained and easy excuse for poor craftsmanship, mixed results, and a general air that doesn't inspire confidence nor demonstrate integrity or attention to detail.)

m-7761 commented 7 years ago

Happy to report that I got the X11 copy server working!

When I first looked at it it seemed to me like freeglut had a monopoly on the XEvent queue. But I was thinking in Windows' way.

After a night's rest I woke up inspired (elves in the back of my head solve all my problems by night) realizing that the ICCCM was a service and so not really an API and so XOpenDisplay could open a second Xlib queue on the same display as the GLX context.

The way X11 does copy semantics for common types is pretty ridiculous. So it means the owner of the selection must have an event queue listener for queries about the content. For this reason I made GLUI's glutIdleFunc mandatory, even though it had been disabled with a "// FIXME! 100% CPU usage!" note.

It does the copy-request queue in the idle. I noticed that GLFW and a Mac GLUT implementation here ( https://github.com/alecjacobson/glut ) are sporting clipboard code. I think probably freeglut should add it too. Are you familiar with that Mac GLUT @nigels-com ? It mentions Cocoa. I don't know if it's pure Objective-C or if it could be used with GLUI.

I could mine it for its clipboard code if so. Surely Apple's isn't as bad as X11! I think opening the X11 server up could work on OS X machines. If they have an Xlib package it should, even if sub-optimal. I think they have a special XQuartz server which might have to be run separately.

P.S. Xming worked (with Cygwin!) to fill the void of the likely buggy Cygwin/X server.

EDITED: I actually took a look at the GLFW code, and I cannot be sure if it facilitates Ctrl+C. I assume it does, but it seemed to be missing essential logic. It seemed to be interested in drag-and-drop, and so it may be there to drop files on top of a window to open them.

m-7761 commented 5 years ago

FWIW I don't know where this ended up, but I'm going to be including clipboard again when I submit a major refactor soon.

I don't see why the needs_idle check can't factor into itself if the clipboard (X11) is serving copied text. That should only come into play if the user has copied text. Implementing a location-bar is impossible without copy/paste, since you don't usually write URLs manually.

Windows doesn't require idle. But GLUT must idle its X client anyway, so I don't see how this is a problem for GLUI. If GLUI thinks not idling means drawing, then it can just take a different path when it idles the clipboard. X11 users could be left out in the cold if overblown concerns remain.

I don't expect the new submission to be accepted, so I am just doing another PR with a full fork of the work. I think the correct back-compat strategy is to make a new header for GLUI that is glui.hpp or something else, and new code can use that, and glui.h can include that, and also fill out a deprecated/back-compat profile for old code using glui.h (which will probably be all code, unless my refactor encourages future work on GLUI. It will look a lot less like basket-case code refactored.)

m-7761 commented 5 years ago

I've refined this (not in this PR but in the refactor I'm working on) to not use idle, but to use glutTimerFunc. That's a better, and less invasive way. Now that I understand the ins-and-outs better.

I've also made it to close the X11 listener when the clipboard is not owned by GLUI. And I think also to let setting the clipboard to an empty string relinquish it. But I'm fuzzy on that because the X11 docs are pretty unclear. I assume it means "unowned" is as-if there is no selection, but it doesn't come right out and say that. So it's fishy.

I haven't built it yet for GLX, but I've set the timer to every 250ms. X11 clipboards are usually pretty unresponsive in my experience.... at least they are on Windows systems. The time is passed to the timer, so maybe it could start out more responsive, but trail off if so, to lighten the load.

nigels-com commented 5 years ago

The pull request was declined, closing this.