osxmidi/LinVst

Alternative -DNOFOCUS mode

Goli4thus opened this issue · 15 comments

This is a feature request based on the outcome of #222.

Suggestions

It would be helpful to have an alternative -DNOFOCUS like mode to build and improve upon some legacy behavior (tag 3.15).

Once built with the new compile flag, it would behave like this:

  1. hovering mouse over plugin window does not auto-focus plugin window (only clicking it will; same as with -DNOFOCUS)
  2. even if plugin window has focus, all keyboard input will be forwarded to host (e.g. reaper)
    • i.e. all keys (letters, number, special characters, function keys, etc.)
    • only keyboard modifiers in conjunction with mouse actions will have a resp. effect on plugin window (e.g. shift + scroll)
  3. to get keyboard input to be capture by plugin window, one needs to hold shift while hovering over or clicking into the plugin window:
    • from then on, all keyboard input will be forwarded to plugin window (e.g. allows for proper text input into input fields)
    • hovering mouse over plugin window with shift being held likely also would focus plugin window as with the default behavior without any -DNOFOCUS like flag (having keyboard input being captured by plugin window even if it doesn't have focus likely goes against current paradigm)

Side notes

That whole "hover over plugin window with holding shift" part is certainly inspired by a behavior I've seen with yabridge when trying it out recently (just to see what it offers).
But the above described behavior in it's entirety isn't something that even yabridge has right now.

And the reason for suggesting making this a separate compile flag is simply that I assume there are users of linvst that rely on the current behavior of -DNOFOCUS.

Would this technically be possible? Any other thoughts or critique?

This is a feature request based on the outcome of #222.

Suggestions

It would be helpful to have an alternative -DNOFOCUS like mode to build and improve upon some legacy behavior (tag 3.15).

Once built with the new compile flag, it would behave like this:

1. hovering mouse over plugin window does not auto-focus plugin window (only clicking it will; same as with `-DNOFOCUS`)

2. even if plugin window has focus, all keyboard input will be forwarded to host (e.g. `reaper`)
   
   * i.e. all keys (letters, number, special characters, function keys, etc.)
   * only keyboard modifiers in conjunction with mouse actions will have a resp. effect on plugin window (e.g. `shift + scroll`)

3. to get keyboard input to be capture by plugin window, one needs to hold `shift` while hovering over or clicking into the plugin window:
   
   * from then on, all keyboard input will be forwarded to plugin window (e.g. allows for proper text input into input fields)
   * hovering mouse over plugin window with `shift` being held likely also would focus plugin window as with the default behavior without any `-DNOFOCUS` like flag (having keyboard input being captured by plugin window even if it doesn't have focus likely goes against current paradigm)

Side notes

That whole "hover over plugin window with holding shift" part is certainly inspired by a behavior I've seen with yabridge when trying it out recently (just to see what it offers). But the above described behavior in it's entirety isn't something that even yabridge has right now.

And the reason for suggesting making this a separate compile flag is simply that I assume there are users of linvst that rely on the current behavior of -DNOFOCUS.

Would this technically be possible? Any other thoughts or critique?

I'll look into it and see what is possible, it might take a while though.

If I can get any progress on it I'll post back in this issue.

Thanks for considering and please don't stress yourself too much about this!
In any case, I will give it a try if there's any kind of draft (e.g. experimental branch).

To quote myself:

3. to get keyboard input to be captured by plugin window, one needs to hold `shift` while hovering over or clicking into the plugin window:

Rereading this part, I think the "clicking into the plugin window" part makes little sense if shift + hovering properly focuses plugin window (same as the default behavior without -DNOFOCUS), which really seems the most "frictionless" approach from a UX / workflow perspective.

I've done a test version that tries to emulate the space bar action of Reaper in Windows.

Don't use -DNOFOCUS, just use the regular Makefile.

Just replace lin-vst-server.cpp with this one.

lin-vst-server.cpp.zip

Thanks for the quick draft!

comparing behavior's of different versions

  • default: (based on commit c18d4a0)
    • once mouse hovers over plugin window, all input is handled like so:
      • event X captured by (host|plugin):
        • spacebar: plugin
        • letters: plugin
        • numbers: plugin
        • special characters: plugin
        • function keys: plugin
    • even if mouse is hovered outside of plugin window, keyboard events are still captured by plugin (focus stays with plugin window)
  • -DNOFOCUS: (based on commit 849813c with -DNOFOCUS flag; Makefile-64bitonly)
    • hovering mouse changes nothing in regards to key event focus:
      • whichever window has focus (reaper or plugin window) receives the key events
    • once plugin window has focus:
      • event X captured by (host|plugin):
        • spacebar: host
        • letters: plugin
        • numbers: plugin
        • special characters: plugin
        • function keys: plugin
  • zip patch: (based on commit c18d4a0, zip patched applied)
    • hovering mouse from focused host (reaper) to plugin window changes focus to plugin window
    • once plugin window has focus:
      • event X captured by (host|plugin):
        • spacebar: host
        • letters: plugin
        • numbers: plugin
        • special characters: plugin
        • function keys: host
    • hovering mouse from focused plugin window back to host (reaper) keeps focus with plugin window

my thoughts on the patch

  • when the plugin window has focus, it certainly aligns with windows and macOS behavior now:
    • function keys being handled by host seemingly is a reaper thing as I've learned today (compared to bitwig)
    • but personally I find those keys in particular very useful to always target the host:
      • but keys like letters, numbers and special characters are indeed not common to reach the host when a plugin window has focus (and it's actually questionable when that ever would make sense considering potential input boxes on plugin window)
      • so the old -DNOFOCUS behavior of 3.15 indeed was a bit special in that regard (and I'm no longer arguing that it should be fully "resurrected" in the current version)
  • when it comes to mouse hover and focus changing:
    • (1) windows and macOS don't change window focus due to mouse hover:
      • so for someone transitioning from one of those OS to linux, it would make most sense to have this is an option
      • maybe this could even be considered as a new default behavior (to make it feel like on those other OS for new users that
        just use the default makefile to get a first impression)
      • but if not, then at least it should be a behavior that's achievable via compile switch(es)
    • (2) regarding the "focus on hover" mechanism:
      • it certainly has it's own charm
      • it's just that having it focus the plugin window, but not focus back the host feels off
      • better would be to also have it focus the host (e.g. reaper) when mouse leaves plugin window
      • but as I said, this might not be wanted by someone coming from another OS
      • therefore just having that "focus/defocus on hover" behavior being its own compile switch would make sense

So concretely, I think this patch is going the right direction! Just points (1) and (2) need some more consideration.

This one takes focus (hover) out.

nofocus.zip

The main reason for the focus (hover) was that the plugin window (which is a wine window) gets focus so that keyboard input could happen with plugins that support keyboard input.

Plugins like FabFilter can do keyboard input with no focus but some others such as TDR plugins need focus for keyboard input, so that's why the hover focus is there.

Anyway, the passing keyboard input to Reaper etc is going to stay because some people (and me) like to use the space bar for stop/play,

This one takes focus (hover) out.
nofocus.zip
The main reason for the focus (hover) was that the plugin window (which is a wine window) gets focus so that keyboard input could happen with plugins that support keyboard input.
Plugins like FabFilter can do keyboard input with no focus but some others such as TDR plugins need focus for keyboard input, so that's why the hover focus is there.

Ok, wasn't aware of that.
I've added AD2 and TDR Nova to the plugins I'm testing these patches on.
But do I understand correctly that even without "focus on hover", as longs I click on the plugin window to focus it, keyboard input regarding input boxes should work? At least that's what I'm observing so far (even with the latest patch).

Anyway, the passing keyboard input to Reaper etc is going to stay because some people (and me) like to use the space bar for stop/play,

Yeah I agree that by default (without users doing anything specific) spacebar should always work for stop/play. But let's look at it in more detail.

the desired behavior

  • (1) host (reaper) has focus:
    • (1.1) mouse over host:
      • event X captured by (host|plugin):
        • spacebar: host
        • letters: host
        • numbers: host
        • special characters: host
        • function keys: host
    • (1.2) mouse hovers over plugin window:
      • same as above
  • (2) plugin window has focus (by being clicked on):
    • (2.1) mouse over plugin window:
      • event X captured by (host|plugin):
        • spacebar: host
        • letters: plugin
        • numbers: plugin
        • special characters: plugin
        • function keys: host
    • (2.2) mouse over host:
      • same as above
  • (3) regarding the problem with spacebar (and function keys) with the above:
    • for those cases when entering spacebar (or function keys if ever needed) on the plugin window might be desired (e.g. search box in AD2), the solution really might be to detect the mouse hovering into plugin window while shift key is being held
    • in that case, linvst could temporarily force all input to be directed to plugin window (or rather wine window as you've mentioned)
      • in a sense, just doing the current default auto-focus on hover behavior when shift is being held

Apart from (3), the above would basically replicate windows and macOS behavior (on those, spacebar handling just "magically" works: if one types inside an input box of a plugin window, it goes towards the plugin window, otherwise to the host (DAW)).

behavior of patch V1 ("lin-vst-server.cpp.zip")

good:

As I've mentioned in previous reply, it does many things correctly of the above desired behavior.

not so good:

  • when host (reaper) has focus:
    • a) the auto-focus on hover of the plugin window
  • when plugin window has focus while inside reaper's FX window container:
    • b) somehow letters, numbers and special characters (or even delete key), while not reaching reaper main window, they
      reach the FX window
      • just try ctrl + a while plugin has focus, it will select all plugins in FX window list
      • does not happen for native linux plugins or stock reaper ones (e.g. ReaEQ)
    • c) spacebar is reaching both reaper and plugin (e.g. AD2 "beats" search box)
      • with point (3) above a clear distinction could be made on when spacebar reaches whom of the two (default reaper,
        with shift + hover into plugin window the plugin window)

behavior of patch V2 ("nofocus.zip")

good:

  • auto-focus on hover is indeed gone now
  • spacebar only reaches reaper, which at least is consistent re input boxes not receiving it by default
  • the issue of patch V1 regarding FX window receiving key events is gone

not so good:

  • once the plugin window has focus (has been clicked on),
    • a) point (2.1) is no longer fulfilled, because function keys no longer reach reaper (just spacebar).
    • b) spacebar never reaches plugin (as a consequence of the new behavior):
      • this could be remedied by point (3), which would redirect spacebar temporarily to plugin (wine) window

At least my impression so far is that apart from the shift key dependant behavior, there's nothing in the above described, desired behavior that isn't already partially fulfilled by certain patches. Really more about combining it into one now (which I'm not implying to be easy).

Here are the problems.

If I could get the mouse button state (ie mouse button down) when the mouse enters the plugin window then I could enable focus for the plugin window when the mouse button is down and the mouse is over the plugin window ie when the mouse is clicked within the plugin window.

Trouble is that I can't do that because X11 doesn't send LinVst mouse events because some other window ie Reaper/Wine has grabbed the mouse events, so all of that is not possible.

I can enable hover focus when the mouse enters the plugin window and then the plugin gets keyboard input.

I can enable focus when a key is pressed (say the up key or maybe shift) and when the mouse enters the plugin window hover focus in enabled otherwise if the key is not pressed hover focus won't be enabled,

I have managed to get some sort of click to focus happening along with the Reaper space bar.

I havn't tested it out much yet.

lin-vst-server.cpp.zip

This latest patch certainly is very close (like 95%) to what I had in mind! IMO the best one so far.

I had a closer look on what you changed and it seems that after all you found a way to detect mouse clicks on the wine window itself!
And as far as I understand it, it really seems like forwarding all key events to reaper is fine, because when reaper notices it doesn't have focus itself, it will ignore everything except spacebar and function keys.

now about the last 5%

When it comes to spacebar, it currently reaches both reaper and plugin window at all times.
For the most part this is just fine, because plugin window usually doesn't care much about spacebar. But when typing into a text box (e.g. TDR Nova) that accepts spacebar, it enters the spacebar in the textbox (good), but also toggles play/stop for reaper (not so good).

What I had in mind was:

  1. by default, only reaper receives spacebar, but not the plugin window
  2. when one holds e.g. shift and hovers into the plugin window, spacebar then no longer reaches reaper, but instead the plugin window

That way one could temporarily prevent reaper from play/stop toggling when typing into an input box on plugin (e.g. a search box for which using spacebar makes sense).

Based on your latest patch, I tried to add this myself, but I only partially succeeded. See here:

patch_V3_plus_shift_hover.zip

When shift + hover is used, temporarily reaper won't be sent any key events, but only plugin window will see them. This helps prevent the play/stop toggling during input box usage.

The thing that I couldn't figure out was how to prevent plugin window from seeing spacebar by default.
So far, I've only added a commented placeholder "if-clause" in that wine event loop (easy to spot in diff), which would be the place when blocking spacebar for the plugin window would be done.

Maybe you have an idea. If not, this really isn't the end of the world, because it's a very minor thing (just a bit surprising to see spacebar reaching both reaper and plugin window by default).

This latest patch certainly is very close (like 95%) to what I had in mind! IMO the best one so far.

I had a closer look on what you changed and it seems that after all you found a way to detect mouse clicks on the wine window itself! And as far as I understand it, it really seems like forwarding all key events to reaper is fine, because when reaper notices it doesn't have focus itself, it will ignore everything except spacebar and function keys.

now about the last 5%

When it comes to spacebar, it currently reaches both reaper and plugin window at all times. For the most part this is just fine, because plugin window usually doesn't care much about spacebar. But when typing into a text box (e.g. TDR Nova) that accepts spacebar, it enters the spacebar in the textbox (good), but also toggles play/stop for reaper (not so good).

What I had in mind was:

1. by default, only reaper receives `spacebar`, but not the plugin window

2. when one holds e.g. `shift` and hovers into the plugin window, `spacebar` then no longer reaches reaper, but instead the plugin window

That way one could temporarily prevent reaper from play/stop toggling when typing into an input box on plugin (e.g. a search box for which using spacebar makes sense).

Based on your latest patch, I tried to add this myself, but I only partially succeeded. See here:

patch_V3_plus_shift_hover.zip

When shift + hover is used, temporarily reaper won't be sent any key events, but only plugin window will see them. This helps prevent the play/stop toggling during input box usage.

The thing that I couldn't figure out was how to prevent plugin window from seeing spacebar by default. So far, I've only added a commented placeholder "if-clause" in that wine event loop (easy to spot in diff), which would be the place when blocking spacebar for the plugin window would be done.

Maybe you have an idea. If not, this really isn't the end of the world, because it's a very minor thing (just a bit surprising to see spacebar reaching both reaper and plugin window by default).

That's good.

I didn't think it was possible to get a mouseclick on the plugin window but now I have 2 different methods.

This one uses a windows setcursor message to get the mouseclick and is the best imo

lin-vst-server.cpp.zip

I'll have a look at the Reaper/plugin spacebar problem.

What I can do is something like, if Capslock is temporarily on for entering space then space won't be passed on to Reaper or the Daw.

Something like this

lin-vst-server.cpp.zip

That's good.

I didn't think it was possible to get a mouseclick on the plugin window but now I have 2 different methods.

This one uses a windows setcursor message to get the mouseclick and is the best imo

lin-vst-server.cpp.zip

I'll have a look at the Reaper/plugin spacebar problem.

The behavior in this patch V4 is the same as patch V3 (for end user). But I see the logic is now attached via a different approach. So both work fine, whatever you prefer.

What I can do is something like, if Capslock is temporarily on for entering space then space won't be passed on to Reaper or the Daw.

Something like this

lin-vst-server.cpp.zip

Also tried this just now.
I don't think capslock is a good idea. Just imagine typing something like "kick long V3" into a search box:

  1. focus input box
  2. "kick"
  3. caps lock toggled on
  4. LMB click in plugin window
  5. spacebar
  6. caps lock toggled off
  7. "long"
  8. caps lock toggled on
  9. LMB click in plugin window
  10. spacebar
  11. caps lock toggled off
  12. "V3"

That's way too cumbersome.

And actually, this is not what I couldn't get to work with the patch I had attached.
I'm not sure if you've tried it, but for the above, it just needs this:

  1. hold shift and hover mouse over plugin window
  2. focus input box
  3. type "kick long V3"
  4. move mouse out/in again regarding plugin window (nothing held) to get back to spacebar working for reaper

I'd say that's much easier.

Please read my previous post again. The issue is not about blocking spacebar from reaching reaper via some mechanism when needed for input box typing (the patch I sent already could do this via the described approach using shift). Just look at the diff. Not much code I added. Can easily be applied to patch V4 as well.

Instead the problem is about preventing spacebar from reaching the plugin by default.
As I wrote back then, this is very minor as one usually doesn't care about spacebar reaching plugin window when it doesn't have any input box focused.
I just thought that maybe you have an idea on how that could be blocked.

But if not, I'd say both patch V3 and patch V4 work already if the small addition I made is added. It then certainly is a version that's very usable and basically fulfills what this feature request was about.

Then (IMO) all that's left is deciding on whether this should become the new default behavior or if it should be put behind a compile flag.

Instead of all this hassle it's better to implementa blacklist of keyboard characters. For example in reaper u need spacebar to play, ctrl-b to switch on/off selected plugin, ctrl-shift-b to disable plugin, arrows to select next/previous plugin. Each daw has own set of shortcuts. So the blacklist should instruct linvst which keys to leave reserved for daw use

Another way is to make shortcut via xdotool to unfocuse plugingui, then u can use daw commands, a perhaps another short cut to focus plugin gui. Still better than holding shift or whatever. Xdotool is real savior. It's replica of windows autoit. But sometimes even clicking outside plugin gui fails to unfocus it. So kind of blacklist is needed on the level of the bridge.

Also development of daws is crappy. They never implement anything to ease use. For example they could assign unique numbers to all plugin gui controls, then after pressing needed number u could change the value by arrows instead of using mouse which is only good for drawing automation lines. There was max freeze wrapper plugin for vsts that patched them to support fxp import. Now such patchers are kind of prohibited and entire progress in software development is under rigid control of the bad ones.