Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow libmpv frontends for better window-dragging implementation #12782

Open
stax76 opened this issue Oct 30, 2023 · 7 comments
Open

Allow libmpv frontends for better window-dragging implementation #12782

stax76 opened this issue Oct 30, 2023 · 7 comments

Comments

@stax76
Copy link
Contributor

stax76 commented Oct 30, 2023

For a libmpv frontend to fully support 3rd party OSCs like uosc and support window-dragging, it's necessary to know if the mouse is inside an OSC menu, in this case dragging is undesired.

I couldn't find a way to get this information, so I use a workaround, I simply do no dragging when the mouse is near a window border because OSC menus are usually found near window borders.

If the menu is in the middle, like the context menu of uosc, dragging is still performed. I didn't know uosc is very popular and doesn't fully work in mpv.net until a recent bug report, it works now after delaying the start of the drag operation for a few pixels.

So currently there are two minor defects in my frontend, dragging works only in the middle of the window, not near borders, and if there is a menu in the middle of the window dragging is still performed.

I looked at the mpv code today and what I found is that it appears to hit test here:

static bool test_mouse(struct input_ctx *ictx, int x, int y, int rej_flags)
{
    input_lock(ictx);
    bool res = false;
    for (int i = 0; i < ictx->num_active_sections; i++) {
        struct active_section *as = &ictx->active_sections[i];
        if (as->flags & rej_flags)
            continue;
        struct cmd_bind_section *s = get_bind_section(ictx, bstr0(as->name));
        if (s->mouse_area_set && test_rect(&s->mouse_area, x, y)) {
            res = true;
            break;
        }
    }
    input_unlock(ictx);
    return res;
}

Now if there was a hit test function either in client.h or as input command, it would solve my problem, or maybe there is already something I could use, or something simpler.

@stax76
Copy link
Contributor Author

stax76 commented Oct 30, 2023

Overall, there are 3 features in mpv.net that need to know if the mouse is in inside an OSC menu:

  1. window-dragging
  2. Cursor hiding
  3. Showing the context menu

@stax76
Copy link
Contributor Author

stax76 commented Nov 4, 2023

I added a description of the issue to the mpv.net manual:

For mpv.net it's currently not possible to find out where OSC menus are located,
but there are 3 features that require this information, therefore mpv.net
makes the assumption that near the window borders might be OSC menus. As a result
the following three features, work only when invokes from the center of the window:

  1. Window dragging (moving the window with the mouse).
  2. Showing the context menu.
  3. Auto hiding the mouse cursor.

When the mouse is near a window border, these 3 features are not available.

@Dudemanguy
Copy link
Member

Dudemanguy commented Nov 4, 2023

Would it suffice to simply add a user-data property boolean to osc.lua that tells you if the mouse is over the osc menus or not? It sounds like that's all you really need from us.

@stax76
Copy link
Contributor Author

stax76 commented Nov 4, 2023

In this case, all OSC scripts would have to do the same, there are about ten OSC scripts available.

I don't know if it would be as fast and reliable as a client.h function.

@Dudemanguy
Copy link
Member

I think currently this works via input sections which I'm truthfully not familiar with. I'm not sure why libmpv behavior would be any different though. It should be the same (in theory anyway).

@stax76
Copy link
Contributor Author

stax76 commented Nov 5, 2023

Frontends always implement their own main window, so they need their own window dragging code, and code to show a context menu and code to auto hide the cursor, but it's not possible to do exactly without a hit test function. The only thing that can be done is creating permanent dead zones near the window borders. It can be perceived as bug or limitation. mpv.net currently uses:

    bool IsMouseInOsc()
    {
        Point pos = PointToClient(MousePosition);
        float top = 0;

        if (!Player.Border)
            top = ClientSize.Height * 0.1f;

        return pos.X < ClientSize.Width * 0.1 ||
               pos.X > ClientSize.Width * 0.9 ||
               pos.Y < top ||
               pos.Y > ClientSize.Height * 0.78;
    }

So the dead zones are:

Left: 10%
Top: 10%, but only if border=no
Right: 10%
Bottom: 22%

@na-na-hi
Copy link
Contributor

na-na-hi commented Jun 8, 2024

In general, all libmpv clients are on equal grounds and compete for shared resources. I think it's up to the clients to resolve any outstanding conflicts, so user-data is a suitable solution.

Also note that currently some OSC implementations (including the built-in OSC and uosc) use the internal allow-hide-cursor+allow-vo-dragging input section flags to control the hide cursor and window dragging behavior. These scripts eventually need to stop using this mechanism, since input section is deprecated and may be removed in the future. Once input section is removed, there is no way for mpv to know the region which has these properties, so providing such feature is impossible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants