Page 1 of 1

[Solved/NoBug] Shift key states don't lose focus

Posted: Fri Jan 03, 2014 14:18
by slack41
I'm just starting with CEGUI and learned with great delight that the edit box widget supports all kinds of line editing, like word-wise cursor movements and copy paste, and bidirectional selections. Great job!

Here's one small nitpick: I implemented some logic for copy-pasting, which consists of remembering whether the Ctrl key is being held. I noticed that you can trick this logic by unfocussing the window while the Ctrl key is held and releasing it while focussing on some other window. To fix this, I'm resetting the Ctrl state when I get a "focus gain" event, and this is working as far as my clipboard handling is concerned. However, the edit box widget itself doesn't seem to reset the state of Ctrl properly, so if you hold Ctrl, focus away, release Ctrl elsewhere, and come back, then the edit box will still think that Ctrl is being pressed, and the cursor moves around word-wise.

I suppose that a fix for this would consist of resetting the Ctrl states of all the widgets when the window regains focus, or perhaps to expose an interface that allows the user to reset those states.

What do you think?

Re: [Bug?] Shift key states don't lose focus

Posted: Fri Jan 03, 2014 22:57
by Ident
Your topic says "shift key states don't lose focus" but your text is about CTRL. How do you figure if an editbox has the ctrl state set or not? Could you show me a code snippet?

Re: [Bug?] Shift key states don't lose focus

Posted: Fri Jan 03, 2014 23:42
by slack41
Ah, sorry, the title is referring to "shift states" on a general level, including Meta, Greek, Hyper, Control, and whatnot. I'm assuming that CEGUI is keeping track of more than just Control :-)

Code goes like this:

Code: Select all

    case sf::Event::KeyPressed:
      if (Event.key.code == sf::Keyboard::LControl || Event.key.code == sf::Keyboard::RControl)
      {
        mControlHeld = true;
      }
      else if (Event.key.code == sf::Keyboard::V && mControlHeld)
      {
        if (CEGUI::Window * w = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getActiveChild())
        {
          return w->performPaste(*CEGUI::System::getSingleton().getClipboard());
        }
      }
      else if (Event.key.code == sf::Keyboard::X && mControlHeld)
      {
        if (CEGUI::Window * w = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getActiveChild())
        {
          return w->performCut(*CEGUI::System::getSingleton().getClipboard());
        }
      }
      else if (Event.key.code == sf::Keyboard::C && mControlHeld)
      {
        if (CEGUI::Window * w = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getActiveChild())
        {
          return w->performCopy(*CEGUI::System::getSingleton().getClipboard());
        }
      }
      return CEGUI::System::getSingleton().getDefaultGUIContext().injectKeyDown(toCEGUIKey(Event.key.code));

    case sf::Event::GainedFocus:
      mControlHeld = false;
      return true;

Here "mControlHeld" is a boolean initialized to "false"; it keeps track of whether Control is currently being held down.

As you can see, I'm taking care to release the "Control is held" state if I ever regain focus, because I don't know what was happening while I didn't have the focus. This is working for my copy/paste logic; it seems that the CEGUI edit box widget itself isn't doing something like this.

Re: [Bug?] Shift key states don't lose focus

Posted: Sat Jan 04, 2014 00:06
by slack41
To add to this, the actual Shift key is also affected: Hold down shift, focus away, release shift, and when you come back, simple cursor movement in an edit box starts selecting text.

Re: [Bug?] Shift key states don't lose focus

Posted: Sat Jan 04, 2014 16:34
by Kulik
Just curious, why aren't you calling injectCopyRequest and injectPasteRequest instead of doing it manually like this?

Re: [Bug?] Shift key states don't lose focus

Posted: Sat Jan 04, 2014 20:46
by slack41
Kulik wrote:Just curious, why aren't you calling injectCopyRequest and injectPasteRequest instead of doing it manually like this?

Because I hadn't known about it - thanks :-)

That just saves me from looking up the active window, though, right? I still have to watch out for the actual Ctrl-X/C/V keystrokes, though?

Re: [Bug?] Shift key states don't lose focus

Posted: Sun Jan 05, 2014 14:20
by Kulik
Yeah, when I implemented this I didn't want to force any sort of shortcut for copy and paste because different platforms handle this differently and copy/pasting on a touch screen is entirely different, etc...

It's up to you to figure out when to inject the copy/cut/paste requests. However you can keep the current control key states in your input injector which should get rid of the active window problem. You are basically going to listen to CTRL_UP and CTRL_DOWN events, update mControlHeld appropriately. When C, X or V is released (C_UP, X_UP, V_UP) you will check if Control is currently held. If so you will inject the requests.

Re: [Bug?] Shift key states don't lose focus

Posted: Tue Jan 07, 2014 07:39
by slack41
Kulik wrote:It's up to you to figure out when to inject the copy/cut/paste requests. However you can keep the current control key states in your input injector which should get rid of the active window problem. You are basically going to listen to CTRL_UP and CTRL_DOWN events, update mControlHeld appropriately. When C, X or V is released (C_UP, X_UP, V_UP) you will check if Control is currently held. If so you will inject the requests.

Sorry if I'm not following entirely, but I think that's what I am indeed doing. The problem I'm describing is that I don't necessarily receive the CTRL_UP event, since the key may be released while my application doesn't have the focus. In other words, I don't really know what the state of the keyboard is, I only know what the keyboard is doing while my application is in the foreground. So to deal with this I want to reset my entire memory of keyboard events every time my application loses and regains focus, if that makes sense.

(This isn't a big problem at all. It's just one of those tiny nitpicks that, when I run into it on the odd occasion, I always wish I could polish a bit better.)

Re: [Bug?] Shift key states don't lose focus

Posted: Tue Jan 07, 2014 16:37
by Ident
Okay now I really get your problem. However, you should be aware of the fact that applications are not generally supposed to catch key events from the outside. Otherwise it would be really easy for any application to retrieve your online-banking account data etc. while you use your browser simultaneously while the application runs :twisted: I guess this could be done anyways in some input libraries with some tricks but I am pretty sure in general this possibility is not provided and the operating systems won't allow it
What could be done is that we check when a window loses focus and in that case fire key release and mousebutton release events for buttons that are considered pressed. Checking if a window has focus depends on the type of application (and/or renderer and input library) you use. So this would have to be done for all different renderers differently i suppose. The input injection however lies in your hands. So it is up to you to inject these things into CEGUI. Therefore it is actually not a CEGUI bug at all. CEGUI does not even register for the event handlers for any application window focus loss events. There is no way CEGUI would know.

Kulik or timotei have to correct me if I am wrong.

Re: [Bug?] Shift key states don't lose focus

Posted: Wed Jan 08, 2014 09:53
by mmixLinus
Sounds right to me.
@slack41, if your main window loses focus you need to inject fake release key/button messages.

A classic (for me at least) was Alt-Tab in Windows. When the window regains focus Alt has been "down" all the time, and stays down until I press/release Alt again.

/mmixLinus

Re: [Bug?] Shift key states don't lose focus

Posted: Wed Jan 08, 2014 13:16
by Kulik
mmixLinus wrote:A classic (for me at least) was Alt-Tab in Windows. When the window regains focus Alt has been "down" all the time, and stays down until I press/release Alt again.


Indeed. It's not really a CEGUI issue and as far as I know we can't really do anything about it. And this bug is in many commercial games. Starcraft 2 for example. Try to Alt+Tab and then go back in and press mouse button. You will ping the map because SC2 thinks Alt is still pressed.

I think they have unbuffered input with events being handled but they cache control keys based on these inputs. This is the weakness of this arrangement.

What you could do about it is to reset all control states when your application gains focus. You will get the opposite bug which is less harmful (I think). Now if you keep Alt pressed and go back to the app the app won't know Alt is pressed until after you release and press it again. Not as big a deal as control keys being stuck.

Re: [Bug? -> WAI] Shift key states don't lose focus

Posted: Sat Jan 11, 2014 15:21
by slack41
You're right, this makes sense. I was overthinking this. Reinjecting release events does indeed sound like the right approach; the interna of the UI widgets shouldn't be my business.

Resolving this as "working as intended" then.Thanks a lot, and sorry for the hassle!