Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Detecting IF a key is being pressed

Detecting IF a key is being pressed

Scheduled Pinned Locked Moved Solved General and Desktop
19 Posts 4 Posters 6.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    NightShadeI
    wrote on 6 Jun 2023, 01:21 last edited by NightShadeI 6 Jun 2023, 01:22
    #1

    We have keyPressEvent and keyReleaseEvent , but this doesn't seem to be enough

    i've been using the approach outlined here of keeping a map if they are pressed or not. This works, until you start dragging the OS window around and key events aren't captured (presumably since the event thread is busy handling the drag), which can result in the key map thinking a key is pressed but it isn't

    A solution might be to just not allow key events while the window is being dragged , if so is that possible in QT? How would I detect events aren't being processed?

    Even better is there any better current modern way as of QT 6.5.X to handle this? I'd prefer not to have to depend on another library if possible or start implementing solutions for different operating systems , which isn't very cross platform friendly

    Also not looking for modifier key solutions, need something for things such as arrow keys

    K 1 Reply Last reply 6 Jun 2023, 01:26
    0
    • N NightShadeI
      6 Jun 2023, 01:21

      We have keyPressEvent and keyReleaseEvent , but this doesn't seem to be enough

      i've been using the approach outlined here of keeping a map if they are pressed or not. This works, until you start dragging the OS window around and key events aren't captured (presumably since the event thread is busy handling the drag), which can result in the key map thinking a key is pressed but it isn't

      A solution might be to just not allow key events while the window is being dragged , if so is that possible in QT? How would I detect events aren't being processed?

      Even better is there any better current modern way as of QT 6.5.X to handle this? I'd prefer not to have to depend on another library if possible or start implementing solutions for different operating systems , which isn't very cross platform friendly

      Also not looking for modifier key solutions, need something for things such as arrow keys

      K Offline
      K Offline
      Kent-Dorfman
      wrote on 6 Jun 2023, 01:26 last edited by
      #2

      @NightShadeI

      Your problem description needs clarification. Please outline the EXACT conditions under which the event check is failing.

      Understand that the keyboard events are only triggered for the application window that has focus. You cannot expect a Qt app to handle keypress events for the OS, when the application doesn't have focus.

      N 1 Reply Last reply 6 Jun 2023, 01:30
      0
      • K Kent-Dorfman
        6 Jun 2023, 01:26

        @NightShadeI

        Your problem description needs clarification. Please outline the EXACT conditions under which the event check is failing.

        Understand that the keyboard events are only triggered for the application window that has focus. You cannot expect a Qt app to handle keypress events for the OS, when the application doesn't have focus.

        N Offline
        N Offline
        NightShadeI
        wrote on 6 Jun 2023, 01:30 last edited by NightShadeI 6 Jun 2023, 01:30
        #3

        @Kent-Dorfman

        This is while it still has focus, and infact I mark all keys as not pressed when QEvent::WindowDeactivate is received

        To reproduce on Windows 10 for example you would:

        1. Hold 'W' key (for example), observe keyPressedEvent is called
        2. Start dragging the window while still holding W key, with your mouse. By dragging the window I mean clicking and holding on the window title bar and moving the mouse
        3. Release the 'W' key while still dragging. Observe the keyReleaseEvent is not called while this occurs.
        4. You will therefore get into some state with the window focused, and the application thinks the 'W' is still pressed, but it is not
        K C 2 Replies Last reply 6 Jun 2023, 01:37
        0
        • N NightShadeI
          6 Jun 2023, 01:30

          @Kent-Dorfman

          This is while it still has focus, and infact I mark all keys as not pressed when QEvent::WindowDeactivate is received

          To reproduce on Windows 10 for example you would:

          1. Hold 'W' key (for example), observe keyPressedEvent is called
          2. Start dragging the window while still holding W key, with your mouse. By dragging the window I mean clicking and holding on the window title bar and moving the mouse
          3. Release the 'W' key while still dragging. Observe the keyReleaseEvent is not called while this occurs.
          4. You will therefore get into some state with the window focused, and the application thinks the 'W' is still pressed, but it is not
          K Offline
          K Offline
          Kent-Dorfman
          wrote on 6 Jun 2023, 01:37 last edited by Kent-Dorfman 6 Jun 2023, 01:38
          #4

          @NightShadeI
          Just a WAG here, but it probably depends upon your defintiion of in-focus, since I would argue that while moving the app window that the window manager has focus.

          My guess is that you will have to cache that keyboard state information in the callbacks that are executed when you handle the window decorations: size() move() callbacks, etc. and even that might not solve your problem.

          N 1 Reply Last reply 6 Jun 2023, 01:42
          0
          • K Kent-Dorfman
            6 Jun 2023, 01:37

            @NightShadeI
            Just a WAG here, but it probably depends upon your defintiion of in-focus, since I would argue that while moving the app window that the window manager has focus.

            My guess is that you will have to cache that keyboard state information in the callbacks that are executed when you handle the window decorations: size() move() callbacks, etc. and even that might not solve your problem.

            N Offline
            N Offline
            NightShadeI
            wrote on 6 Jun 2023, 01:42 last edited by NightShadeI 6 Jun 2023, 01:42
            #5

            @Kent-Dorfman

            Yes I would agree, since im using the definition of when QT itself thinks its in focus or not and QT does think a window is in focus as it is being dragged, So I need some way to reconcile the fact that I shoudln't expect to receive events while that is happening. This is ultimately my question (how should I do this?)

            K 1 Reply Last reply 6 Jun 2023, 01:49
            0
            • N NightShadeI
              6 Jun 2023, 01:42

              @Kent-Dorfman

              Yes I would agree, since im using the definition of when QT itself thinks its in focus or not and QT does think a window is in focus as it is being dragged, So I need some way to reconcile the fact that I shoudln't expect to receive events while that is happening. This is ultimately my question (how should I do this?)

              K Offline
              K Offline
              Kent-Dorfman
              wrote on 6 Jun 2023, 01:49 last edited by
              #6

              @NightShadeI
              I got nothing, because I have never encountered the need to handle key events while moving windows.

              N 1 Reply Last reply 6 Jun 2023, 02:00
              0
              • K Kent-Dorfman
                6 Jun 2023, 01:49

                @NightShadeI
                I got nothing, because I have never encountered the need to handle key events while moving windows.

                N Offline
                N Offline
                NightShadeI
                wrote on 6 Jun 2023, 02:00 last edited by NightShadeI 6 Jun 2023, 02:01
                #7

                @Kent-Dorfman

                That's fine, can leave for someone else to answer.

                Just to be clear to anyone reading, the aim isn't necessarily to handle key events while the window is moving (although it is still a win if I can)

                The aim is just to detect that i'm in some state where events cannot be handled, so it might be better to wipe my map of "keys currently being pressed" , to maintain some invariant , and not be left in a bad state

                Or even provide a solution that will allow me to forego the use of this stateful map, (example querying the keyboard state during painting instead of relying on my own map)

                N 1 Reply Last reply 6 Jun 2023, 03:41
                0
                • N NightShadeI
                  6 Jun 2023, 02:00

                  @Kent-Dorfman

                  That's fine, can leave for someone else to answer.

                  Just to be clear to anyone reading, the aim isn't necessarily to handle key events while the window is moving (although it is still a win if I can)

                  The aim is just to detect that i'm in some state where events cannot be handled, so it might be better to wipe my map of "keys currently being pressed" , to maintain some invariant , and not be left in a bad state

                  Or even provide a solution that will allow me to forego the use of this stateful map, (example querying the keyboard state during painting instead of relying on my own map)

                  N Offline
                  N Offline
                  NightShadeI
                  wrote on 6 Jun 2023, 03:41 last edited by NightShadeI 6 Jun 2023, 05:46
                  #8

                  @NightShadeI

                  Another update: I think this problem is even worse and there seems to be some bug in QT looking more deeply into it

                  After you stop dragging the window, if you press the same key again, it won't register as a key press, but it will register as a key release once you raise the key... (and everything is then consistent again) so this means QT's internal state must be wrong since it seems its also waiting for the key release, which already happened while it was blocked

                  Update 2: Tried on OSX , and it also doesn't work there , so thinking this might be some QT specific bug

                  Update 3:

                  Here is the most minimal code example I could make to reproduce the issue, if you try to move or resize the widget while pressing any keyboard button , the event will never be called:

                  class KeyPressFilter : public QObject {
                  public:
                      bool eventFilter(QObject* aObject, QEvent* aEvent) final {
                          if (aEvent->type() != QEvent::KeyRelease) return QObject::eventFilter(aObject, aEvent);
                          if (!static_cast<QKeyEvent*>(aEvent)->isAutoRepeat()) {
                              std::cout << "Will it be called? Who knows!" << std::endl;
                          }
                          return true;
                      }
                  };
                  
                  int main(int aArgc, char *aArgv[]) {
                      QApplication myApplication{aArgc, aArgv};
                  
                      KeyPressFilter myKeyFilter;
                      myApplication.installEventFilter(&myKeyFilter);
                  
                      QWidget myWidget;
                      myWidget.show();
                  
                      return myApplication.exec();
                  }
                  
                  N 1 Reply Last reply 7 Jun 2023, 04:49
                  2
                  • N NightShadeI
                    6 Jun 2023, 03:41

                    @NightShadeI

                    Another update: I think this problem is even worse and there seems to be some bug in QT looking more deeply into it

                    After you stop dragging the window, if you press the same key again, it won't register as a key press, but it will register as a key release once you raise the key... (and everything is then consistent again) so this means QT's internal state must be wrong since it seems its also waiting for the key release, which already happened while it was blocked

                    Update 2: Tried on OSX , and it also doesn't work there , so thinking this might be some QT specific bug

                    Update 3:

                    Here is the most minimal code example I could make to reproduce the issue, if you try to move or resize the widget while pressing any keyboard button , the event will never be called:

                    class KeyPressFilter : public QObject {
                    public:
                        bool eventFilter(QObject* aObject, QEvent* aEvent) final {
                            if (aEvent->type() != QEvent::KeyRelease) return QObject::eventFilter(aObject, aEvent);
                            if (!static_cast<QKeyEvent*>(aEvent)->isAutoRepeat()) {
                                std::cout << "Will it be called? Who knows!" << std::endl;
                            }
                            return true;
                        }
                    };
                    
                    int main(int aArgc, char *aArgv[]) {
                        QApplication myApplication{aArgc, aArgv};
                    
                        KeyPressFilter myKeyFilter;
                        myApplication.installEventFilter(&myKeyFilter);
                    
                        QWidget myWidget;
                        myWidget.show();
                    
                        return myApplication.exec();
                    }
                    
                    N Offline
                    N Offline
                    NightShadeI
                    wrote on 7 Jun 2023, 04:49 last edited by NightShadeI 6 Jul 2023, 04:51
                    #9

                    Could one of the QT pros give some insight on this? Even if it's just answering I should make a QT bug ticket (if it is one?)

                    Or even if the issue can be reproduced

                    1 Reply Last reply
                    0
                    • N NightShadeI
                      6 Jun 2023, 01:30

                      @Kent-Dorfman

                      This is while it still has focus, and infact I mark all keys as not pressed when QEvent::WindowDeactivate is received

                      To reproduce on Windows 10 for example you would:

                      1. Hold 'W' key (for example), observe keyPressedEvent is called
                      2. Start dragging the window while still holding W key, with your mouse. By dragging the window I mean clicking and holding on the window title bar and moving the mouse
                      3. Release the 'W' key while still dragging. Observe the keyReleaseEvent is not called while this occurs.
                      4. You will therefore get into some state with the window focused, and the application thinks the 'W' is still pressed, but it is not
                      C Offline
                      C Offline
                      CPPUIX
                      wrote on 7 Jun 2023, 13:40 last edited by
                      #10

                      Hi,

                      First, here's my exact environment:

                      • System :
                        • Operating System: KDE neon 5.27
                        • KDE Plasma Version: 5.27.5
                        • KDE Frameworks Version: 5.106.0
                        • Qt Version: 5.15.9
                        • Kernel Version: 5.19.0-41-generic (64-bit)
                        • Graphics Platform: X11

                      • Developing tools :
                        • Qt 6.5.0
                        • CMake 3.22.1
                        • Qt Creator 10.0.1
                        • Kit: Desktop Qt 6.5.0 GCC 64bit

                      @NightShadeI said in Detecting IF a key is being pressed:

                      1. Hold 'W' key (for example), observe keyPressedEvent is called
                      2. Start dragging the window while still holding W key, with your mouse. By dragging the window I mean clicking and holding on the window title bar and moving the mouse
                      3. Release the 'W' key while still dragging. Observe the keyReleaseEvent is not called while this occurs.
                      4. You will therefore get into some state with the window focused, and the application thinks the 'W' is still pressed, but it is not

                      I couldn't reproduce that, key release event gets called while still moving the window or resizing it. I tried different combinations of pressing, releasing, dragging, resizing, all resulted the same.

                      @NightShadeI said in Detecting IF a key is being pressed:

                      After you stop dragging the window, if you press the same key again, it won't register as a key press, but it will register as a key release once you raise the key

                      @NightShadeI said in Detecting IF a key is being pressed:

                      if you try to move or resize the widget while pressing any keyboard button , the event will never be called

                      Wouldn't that be because your MRE only detects key release events.

                      From what I understand, I made my own event filter, here it is:

                      bool eventFilter(QObject* aObject, QEvent* aEvent) final
                          {
                              //detect key release
                              //the current time is just my way of preventing same output of debug messages
                              if (aEvent->type() == QEvent::KeyRelease)
                              {
                                  if (!static_cast<QKeyEvent*>(aEvent)->isAutoRepeat())
                                  {
                                      qDebug() << "Key Released"  << QTime::currentTime();
                                  }
                              }
                              //detect key press
                              if (aEvent->type() == QEvent::KeyPress)
                              {
                                  if (!static_cast<QKeyEvent*>(aEvent)->isAutoRepeat())
                                  {
                                      qDebug() << "Key Pressed"  << QTime::currentTime() << "\n";
                                  }
                              }
                      
                              return QObject::eventFilter(aObject, aEvent);
                          }
                      

                      I tried multiple ways of pressing and releasing again, and everything seems to be normal.

                      I am no expert, just thought I'd share this in case it might be of some help. You can also correct me if I got it wrong (I feel like I'm missing something), to clarify it for others.

                      Good luck!

                      N 1 Reply Last reply 7 Jun 2023, 14:01
                      2
                      • C CPPUIX
                        7 Jun 2023, 13:40

                        Hi,

                        First, here's my exact environment:

                        • System :
                          • Operating System: KDE neon 5.27
                          • KDE Plasma Version: 5.27.5
                          • KDE Frameworks Version: 5.106.0
                          • Qt Version: 5.15.9
                          • Kernel Version: 5.19.0-41-generic (64-bit)
                          • Graphics Platform: X11

                        • Developing tools :
                          • Qt 6.5.0
                          • CMake 3.22.1
                          • Qt Creator 10.0.1
                          • Kit: Desktop Qt 6.5.0 GCC 64bit

                        @NightShadeI said in Detecting IF a key is being pressed:

                        1. Hold 'W' key (for example), observe keyPressedEvent is called
                        2. Start dragging the window while still holding W key, with your mouse. By dragging the window I mean clicking and holding on the window title bar and moving the mouse
                        3. Release the 'W' key while still dragging. Observe the keyReleaseEvent is not called while this occurs.
                        4. You will therefore get into some state with the window focused, and the application thinks the 'W' is still pressed, but it is not

                        I couldn't reproduce that, key release event gets called while still moving the window or resizing it. I tried different combinations of pressing, releasing, dragging, resizing, all resulted the same.

                        @NightShadeI said in Detecting IF a key is being pressed:

                        After you stop dragging the window, if you press the same key again, it won't register as a key press, but it will register as a key release once you raise the key

                        @NightShadeI said in Detecting IF a key is being pressed:

                        if you try to move or resize the widget while pressing any keyboard button , the event will never be called

                        Wouldn't that be because your MRE only detects key release events.

                        From what I understand, I made my own event filter, here it is:

                        bool eventFilter(QObject* aObject, QEvent* aEvent) final
                            {
                                //detect key release
                                //the current time is just my way of preventing same output of debug messages
                                if (aEvent->type() == QEvent::KeyRelease)
                                {
                                    if (!static_cast<QKeyEvent*>(aEvent)->isAutoRepeat())
                                    {
                                        qDebug() << "Key Released"  << QTime::currentTime();
                                    }
                                }
                                //detect key press
                                if (aEvent->type() == QEvent::KeyPress)
                                {
                                    if (!static_cast<QKeyEvent*>(aEvent)->isAutoRepeat())
                                    {
                                        qDebug() << "Key Pressed"  << QTime::currentTime() << "\n";
                                    }
                                }
                        
                                return QObject::eventFilter(aObject, aEvent);
                            }
                        

                        I tried multiple ways of pressing and releasing again, and everything seems to be normal.

                        I am no expert, just thought I'd share this in case it might be of some help. You can also correct me if I got it wrong (I feel like I'm missing something), to clarify it for others.

                        Good luck!

                        N Offline
                        N Offline
                        NightShadeI
                        wrote on 7 Jun 2023, 14:01 last edited by NightShadeI 6 Jul 2023, 14:05
                        #11

                        @Abderrahmene_Rayene

                        Very much appreicate the attempt to reproduce! I don't have some sort of linux OS I can work with , so maybe it is only specific to OSX and Windows? Either way appreciate you helping with the investigation on this issue :)

                        I believe you have understood perfectly

                        Wouldn't that be because your MRE only detects key release events.

                        Just to clarify, I use keyPress and keyRelease in my actual code, just used keyRelease only in MRE to give the shorest possible code , as to try not to detour people , since both highlight the issue

                        C 1 Reply Last reply 7 Jun 2023, 14:06
                        0
                        • N NightShadeI
                          7 Jun 2023, 14:01

                          @Abderrahmene_Rayene

                          Very much appreicate the attempt to reproduce! I don't have some sort of linux OS I can work with , so maybe it is only specific to OSX and Windows? Either way appreciate you helping with the investigation on this issue :)

                          I believe you have understood perfectly

                          Wouldn't that be because your MRE only detects key release events.

                          Just to clarify, I use keyPress and keyRelease in my actual code, just used keyRelease only in MRE to give the shorest possible code , as to try not to detour people , since both highlight the issue

                          C Offline
                          C Offline
                          CPPUIX
                          wrote on 7 Jun 2023, 14:06 last edited by CPPUIX 6 Jul 2023, 14:11
                          #12

                          @NightShadeI said in Detecting IF a key is being pressed:

                          just used keyRelease only in MRE to give the shorest possible code , as to try not to detour people , since both highlight the issue

                          I think you should include the key press event as well in your MRE, I thought you missed it.

                          And you're welcome, thanks for providing details, I always appreciate an MRE.

                          1 Reply Last reply
                          0
                          • N Offline
                            N Offline
                            NightShadeI
                            wrote on 9 Jun 2023, 08:50 last edited by NightShadeI 6 Sept 2023, 08:51
                            #13

                            Can one of QT members please clarify if I should be raising a bug for this? Getting pretty desperate and it's still not solved

                            Or is there anything else I should provide?

                            K 1 Reply Last reply 10 Jun 2023, 03:22
                            0
                            • N NightShadeI
                              9 Jun 2023, 08:50

                              Can one of QT members please clarify if I should be raising a bug for this? Getting pretty desperate and it's still not solved

                              Or is there anything else I should provide?

                              K Offline
                              K Offline
                              Kent-Dorfman
                              wrote on 10 Jun 2023, 03:22 last edited by
                              #14

                              @NightShadeI

                              I wouldn't file a bug report unless you are sure they will be able to reproduce the behaviour. That's the key to having it addressed.

                              N 1 Reply Last reply 10 Jun 2023, 14:18
                              0
                              • K Kent-Dorfman
                                10 Jun 2023, 03:22

                                @NightShadeI

                                I wouldn't file a bug report unless you are sure they will be able to reproduce the behaviour. That's the key to having it addressed.

                                N Offline
                                N Offline
                                NightShadeI
                                wrote on 10 Jun 2023, 14:18 last edited by
                                #15

                                @Kent-Dorfman

                                Is there anything else you think I should provide for this? I think I really just need someone else to try this on windows or OSX now, I've given steps and code

                                1 Reply Last reply
                                0
                                • N Offline
                                  N Offline
                                  NightShadeI
                                  wrote on 14 Jun 2023, 09:24 last edited by
                                  #16

                                  @JonB , @SGaist , @Christian-Ehrlicher , @Chris-Kawa or @jsulm

                                  Are any of you able to provide any light on this issue? Thanks :)

                                  Chris KawaC 1 Reply Last reply 14 Jun 2023, 21:38
                                  0
                                  • N NightShadeI
                                    14 Jun 2023, 09:24

                                    @JonB , @SGaist , @Christian-Ehrlicher , @Chris-Kawa or @jsulm

                                    Are any of you able to provide any light on this issue? Thanks :)

                                    Chris KawaC Offline
                                    Chris KawaC Offline
                                    Chris Kawa
                                    Lifetime Qt Champion
                                    wrote on 14 Jun 2023, 21:38 last edited by Chris Kawa
                                    #17

                                    @NightShadeI Well, welcome to the world of pain input handling :) This is not a Qt bug and you're not missing any events. You're just not getting any. There is no state that gets lost in Qt because it holds no state (apart from modifiers). It directly translates the OS messages to you e.g. on Windows the WM_[whatever] native messages. You can install the native event filter on the app object and monitor all the raw messages OS sends to your windows if you want to see for yourself. It's the same if you use MFC or low level WinAPI. They all just work with what the system sends.

                                    A drag is denoted by QEvent::NonClientAreaMouseButtonPress and QEvent::NonClientAreaMouseButtonRelease. I don't know about other OSes and I suspect this could vary on different window managers, but on Windows a window that is being dragged does not receive key press or release events. This means that:

                                    If you press before and release after a drag you will get both events.
                                    If you press before and release during drag you will only get the press event.
                                    If you press during and release after you will only get release.
                                    If you press during, hold long enough to get autorepeat after drag and then release then it gets weird, because the first autorepeat after drag is converted to normal press, so you get normal press, then auto-repeat release without matching press, then a bunch of auto-repeat presses/releases pairs and a finishing normal release.

                                    I'd say it's a very niche corner case that may vary across platforms and there's no point in obsessing over it. The easiest way to handle this not to end up in an inconsistent state is to clear your key map when you get a non-client mouse press. You won't get any key presses until the drag is over and at worst you'll get an unmatched release after, but that's fine, since the map is cleared anyway.

                                    If you want to loose some hair and actually handle this (I would advise against) you'd need to use the platform specific low level input APIs e.g. Direct Input or a keyboard hook with the SetWindowsHookEx API on Windows. I don't know about other OSes, but I suspect they have something similar.

                                    N 2 Replies Last reply 14 Jun 2023, 22:55
                                    7
                                    • Chris KawaC Chris Kawa
                                      14 Jun 2023, 21:38

                                      @NightShadeI Well, welcome to the world of pain input handling :) This is not a Qt bug and you're not missing any events. You're just not getting any. There is no state that gets lost in Qt because it holds no state (apart from modifiers). It directly translates the OS messages to you e.g. on Windows the WM_[whatever] native messages. You can install the native event filter on the app object and monitor all the raw messages OS sends to your windows if you want to see for yourself. It's the same if you use MFC or low level WinAPI. They all just work with what the system sends.

                                      A drag is denoted by QEvent::NonClientAreaMouseButtonPress and QEvent::NonClientAreaMouseButtonRelease. I don't know about other OSes and I suspect this could vary on different window managers, but on Windows a window that is being dragged does not receive key press or release events. This means that:

                                      If you press before and release after a drag you will get both events.
                                      If you press before and release during drag you will only get the press event.
                                      If you press during and release after you will only get release.
                                      If you press during, hold long enough to get autorepeat after drag and then release then it gets weird, because the first autorepeat after drag is converted to normal press, so you get normal press, then auto-repeat release without matching press, then a bunch of auto-repeat presses/releases pairs and a finishing normal release.

                                      I'd say it's a very niche corner case that may vary across platforms and there's no point in obsessing over it. The easiest way to handle this not to end up in an inconsistent state is to clear your key map when you get a non-client mouse press. You won't get any key presses until the drag is over and at worst you'll get an unmatched release after, but that's fine, since the map is cleared anyway.

                                      If you want to loose some hair and actually handle this (I would advise against) you'd need to use the platform specific low level input APIs e.g. Direct Input or a keyboard hook with the SetWindowsHookEx API on Windows. I don't know about other OSes, but I suspect they have something similar.

                                      N Offline
                                      N Offline
                                      NightShadeI
                                      wrote on 14 Jun 2023, 22:55 last edited by
                                      #18

                                      @Chris-Kawa

                                      Thanks for the reply, I can't thank you for it enough. This is super useful and I believe I'll do the former of your approaches, sounds like a lot less of a headache :)

                                      I'll test tonight and mark as solved if all is good! Hope this serves to help many others in future

                                      1 Reply Last reply
                                      0
                                      • Chris KawaC Chris Kawa
                                        14 Jun 2023, 21:38

                                        @NightShadeI Well, welcome to the world of pain input handling :) This is not a Qt bug and you're not missing any events. You're just not getting any. There is no state that gets lost in Qt because it holds no state (apart from modifiers). It directly translates the OS messages to you e.g. on Windows the WM_[whatever] native messages. You can install the native event filter on the app object and monitor all the raw messages OS sends to your windows if you want to see for yourself. It's the same if you use MFC or low level WinAPI. They all just work with what the system sends.

                                        A drag is denoted by QEvent::NonClientAreaMouseButtonPress and QEvent::NonClientAreaMouseButtonRelease. I don't know about other OSes and I suspect this could vary on different window managers, but on Windows a window that is being dragged does not receive key press or release events. This means that:

                                        If you press before and release after a drag you will get both events.
                                        If you press before and release during drag you will only get the press event.
                                        If you press during and release after you will only get release.
                                        If you press during, hold long enough to get autorepeat after drag and then release then it gets weird, because the first autorepeat after drag is converted to normal press, so you get normal press, then auto-repeat release without matching press, then a bunch of auto-repeat presses/releases pairs and a finishing normal release.

                                        I'd say it's a very niche corner case that may vary across platforms and there's no point in obsessing over it. The easiest way to handle this not to end up in an inconsistent state is to clear your key map when you get a non-client mouse press. You won't get any key presses until the drag is over and at worst you'll get an unmatched release after, but that's fine, since the map is cleared anyway.

                                        If you want to loose some hair and actually handle this (I would advise against) you'd need to use the platform specific low level input APIs e.g. Direct Input or a keyboard hook with the SetWindowsHookEx API on Windows. I don't know about other OSes, but I suspect they have something similar.

                                        N Offline
                                        N Offline
                                        NightShadeI
                                        wrote on 15 Jun 2023, 09:57 last edited by
                                        #19

                                        @Chris-Kawa

                                        Works perfectly on both Windows and OSX!

                                        I'll leave a footnote for anyone in future, that it seems that on OSX you have to actually install a event filter into the QApplication to handle the event, the QWidget does not seem to receive this event, where as it seems to on Windows.

                                        Thanks Chris again for the response, will mark as solved

                                        1 Reply Last reply
                                        2
                                        • N NightShadeI has marked this topic as solved on 15 Jun 2023, 09:57

                                        4/19

                                        6 Jun 2023, 01:37

                                        topic:navigator.unread, 15
                                        • Login

                                        • Login or register to search.
                                        4 out of 19
                                        • First post
                                          4/19
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • Users
                                        • Groups
                                        • Search
                                        • Get Qt Extensions
                                        • Unsolved