Mouse Click Grabs keyboard focus in some hosts

A user interface toolkit mainly for audio plug-ins (VST, AudioUnit, etc).
marvin
Posts: 6
Joined: Sun Jul 24, 2016 10:34 pm

Mouse Click Grabs keyboard focus in some hosts

Postby marvin » Sun Jul 24, 2016 10:36 pm

I tried using setWantsFocus(false) on all my controls, but it seems like the mouse click is is grabbing key focus mouse wheel does not do this

Arne Scheffler
Posts: 188
Joined: Mon Jun 20, 2016 7:53 am

Re: Mouse Click Grabs keyboard focus in some hosts

Postby Arne Scheffler » Mon Jul 25, 2016 2:27 pm

Hi Marvin,
can you be more specific ? What Operating System, which hosts, and very important, what do you expect to happen ?

cheers
Arne

marvin
Posts: 6
Joined: Sun Jul 24, 2016 10:34 pm

Re: Mouse Click Grabs keyboard focus in some hosts

Postby marvin » Mon Jul 25, 2016 5:55 pm

This is for both Mac 64bit and Windows 32 with the juce plugin host found here https://www.juce.com. For Mac I'm sure that it's the vst grabbing focus on click specially the cknob since the up down left right key change the parameters I have them all set to wants focus false but they are still grabbing focus. For window it seems like cframe is grabbing focus on click.

marvin
Posts: 6
Joined: Sun Jul 24, 2016 10:34 pm

Re: Mouse Click Grabs keyboard focus in some hosts

Postby marvin » Mon Jul 25, 2016 5:56 pm

I can send my project if necessary since it's a modified version of the plugin host.

marvin
Posts: 6
Joined: Sun Jul 24, 2016 10:34 pm

Re: Mouse Click Grabs keyboard focus in some hosts

Postby marvin » Mon Jul 25, 2016 7:32 pm

Oh sorry I expect the midi computer component key board to set off noteOn events it could be that it is some how giving focus I'm trying to track down the problem now.

Arne Scheffler
Posts: 188
Joined: Mon Jun 20, 2016 7:53 am

Re: Mouse Click Grabs keyboard focus in some hosts

Postby Arne Scheffler » Mon Jul 25, 2016 8:04 pm

Hi Marvin,
it's difficult to follow you.
If you mean that the keyboard focus is shifted to the platform control of VSTGUI if you click inside of it, then this is expected behaviour.
You have to be a good citizen and only handle keyboard input events for the events you are actually using. Do you by any chance have a global keyboard hook registered on the CFrame object ? Then you must make sure to return the correct value when not handling the keyboard event.

cheers
Arne

marvin
Posts: 6
Joined: Sun Jul 24, 2016 10:34 pm

Re: Mouse Click Grabs keyboard focus in some hosts

Postby marvin » Mon Jul 25, 2016 8:18 pm

Hi Arne,
I have no global keyboard hooks registered. My assumption was if I set setWantsKeyboardFocus(false) for each of my objects Cframe and the Controls inside the Cframe that they wouldn't take keyboard focus when clicked on them in the host application. This doesn't occur with mouse wheel events just mouseDown. I will look in global keyboard hooks.
Thanks,
Marvin

ray
Posts: 72
Joined: Fri Sep 02, 2016 9:37 am

Re: Mouse Click Grabs keyboard focus in some hosts

Postby ray » Fri Sep 02, 2016 9:49 am

Hi there,

I think on Windows the problem is located in line 887 in win32frame.cpp. Once the plugin container window receives the focus it also steals the keyboard focus by calling SetFocus(). The keyboard focus isn't returned to the DAW window until the user highlights it again (e.g. by clicking on it), even if the plugin window is closed. Keyboard events, even unprocessed ones, are consequently consumed by your plugin window procedure.

If your CFrame isn't supposed to process any key events, you can safely comment out the SetFocus() line. A clean fix could e.g. forward unprocessed key events to the window that was in focus prior to the plugin container window - which is the window handle returned by SetFocus(), given that it's still valid, of course (beware: Cubase seems to do all kinds of weird things to its windows once you switch between application, i.e. it seems cubase re-builds parts of its window structure when switching the context).

By the way no offense or smart-assing, VSTGUI, escpecially the 4.3 update, is exceptionally good and usable.

Ray

Arne Scheffler
Posts: 188
Joined: Mon Jun 20, 2016 7:53 am

Re: Mouse Click Grabs keyboard focus in some hosts

Postby Arne Scheffler » Mon Sep 05, 2016 3:23 pm

You maybe right. The win32 keyboard handling code is mainly the same since open sourcing VSTGUI. I will analyse it and hopefully find a good fix for it.

ray
Posts: 72
Joined: Fri Sep 02, 2016 9:37 am

Re: Mouse Click Grabs keyboard focus in some hosts

Postby ray » Fri Nov 17, 2017 11:03 am

The described issue is particularly noticeable in Pro Tools on Windows. E.g. it's impossible to trigger the transport via space, once a VSTGUI editor window has been opened unless you give back the focus to Pro Tools by clicking on its window.

Here's a suggestion for a fix in win32frame.h / win32frame.cpp in the current 4.5 build:

Add a member variable to the Win32Frame declaration:

Code: Select all

protected:
   ...
   HWND oldFocusWindow;
   ...


Add the following changes in the Win32Frame implementation:

In the ctor

Code: Select all

..
, oldFocuseWindow (0)
..


In Win32Frame::proc()

Focus acquisition..

Code: Select all

case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_LBUTTONDBLCLK:
case WM_XBUTTONDBLCLK:
   doubleClick = true;
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_XBUTTONDOWN:
{
   CButtonState buttons = 0;
   if (wParam & MK_LBUTTON)
      buttons |= kLButton;
   if (wParam & MK_RBUTTON)
      buttons |= kRButton;
   if (wParam & MK_MBUTTON)
      buttons |= kMButton;
   if (wParam & MK_XBUTTON1)
      buttons |= kButton4;
   if (wParam & MK_XBUTTON2)
      buttons |= kButton5;
   if (wParam & MK_CONTROL)
      buttons |= kControl;
   if (wParam & MK_SHIFT)
      buttons |= kShift;
   if (GetAsyncKeyState (VK_MENU)    < 0)
      buttons |= kAlt;
   if (doubleClick)
      buttons |= kDoubleClick;

   // Keep track of previous focus window
   HWND oldFocus = SetFocus (getPlatformWindow ());
   if (oldFocus != hwnd)
      oldFocusWindow = oldFocus;
   
   CPoint where (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam));
   if (pFrame->platformOnMouseDown (where, buttons) == kMouseEventHandled && getPlatformWindow ())
      SetCapture (getPlatformWindow ());
   return 0;
}


Forward unprocessed key events to the window that was focused previously in case it's still alive in WM_KEYDOWN and WM_KEYUP:

Code: Select all

case WM_KEYDOWN:
{
   VstKeyCode key {};
   if (GetAsyncKeyState (VK_SHIFT)   < 0)
      key.modifier |= MODIFIER_SHIFT;
   if (GetAsyncKeyState (VK_CONTROL) < 0)
      key.modifier |= MODIFIER_CONTROL;
   if (GetAsyncKeyState (VK_MENU)    < 0)
      key.modifier |= MODIFIER_ALTERNATE;
   key.virt = translateWinVirtualKey (wParam);
   if (key.virt)
   {
      if (pFrame->platformOnKeyDown (key))
         return 0;
   }
   
   if (IsWindow (oldFocusWindow))
   {
      WNDPROC oldProc = (WNDPROC) GetWindowLongPtr (oldFocusWindow, GWLP_WNDPROC);
      if (oldProc && oldProc != WindowProc)
         return CallWindowProc (oldProc, oldFocusWindow, message, wParam, lParam);
   }
   break;
}


Code: Select all

case WM_KEYUP:
{
   VstKeyCode key {};
   if (GetAsyncKeyState (VK_SHIFT)   < 0)
      key.modifier |= MODIFIER_SHIFT;
   if (GetAsyncKeyState (VK_CONTROL) < 0)
      key.modifier |= MODIFIER_CONTROL;
   if (GetAsyncKeyState (VK_MENU)    < 0)
      key.modifier |= MODIFIER_ALTERNATE;
      key.virt = translateWinVirtualKey (wParam);
      if (key.virt)
      {
         if (pFrame->platformOnKeyUp (key))
            return 0;
      }
      
      if (IsWindow (oldFocusWindow))
      {
            WNDPROC oldProc = (WNDPROC) GetWindowLongPtr (oldFocusWindow, GWLP_WNDPROC);
            if(oldProc && oldProc != WindowProc)
               return CallWindowProc (oldProc, oldFocusWindow, message, wParam, lParam);
      }
      break;
   }


Release focus..

Code: Select all

case WM_KILLFOCUS:
{
   oldFocusWindow = 0;

   HWND focusWindow = GetFocus ();
   if (GetParent (focusWindow) != windowHandle)
      pFrame->platformOnActivate (false);
   break;
}


Also note that I'm using GetAsyncKeyState() instead of GetKeyState(), though admittedly not very beautiful in particular, the modifier keys will be have been consumed by Pro Tools which apparently grabs them away via a low level API before they reach our window.

It's also a little puzzling why the VstKeyCode structure's character member isn't inizialized in the WM_KEYDOWN / WM_KEYUP handlers, whereas it is in other platform implementations. This basically makes it impossible to capture arbitrary keypresses in windows implementations, right?


Return to “VSTGUI”

Who is online

Users browsing this forum: Google [Bot] and 1 guest