Skip to content

Conversation

Gargaj
Copy link
Contributor

@Gargaj Gargaj commented Oct 17, 2017

This helps a lot when the user drags a slider but carries the cursor offscreen before releasing the button - without the capturing, the slider will "stick" to the mouse cursor even after the button has been released. (This should generally be added to all Windows implementations - I won't mind doing it if you think it's a good idea.)

This helps a lot when the user drags a slider but carries the cursor offscreen before releasing the button - without the capturing, the slider will "stick" to the mouse cursor even after the button has been released. (This should generally be added to all Windows implementations - I won't mind doing it if you think it's a good idea.)
@ocornut ocornut merged commit 839067f into ocornut:master Oct 23, 2017
ocornut added a commit that referenced this pull request Oct 23, 2017
ocornut added a commit that referenced this pull request Oct 23, 2017
…t correct behavior (#1375)

ps: DirectX 12 example (#302) may want to adopt that as well.
@ocornut
Copy link
Owner

ocornut commented Oct 23, 2017

Hello,

This is very much welcome! I didn't know about this API.
I have applied a patch based on yours (which didn't compile as-is, and had an issue when using multiple buttons, e.g if you did left-down, right-down, drag, right-up: the capture would be lost).
It's really unfortunate but SetCapture/ReleaseCapture is surprisingly difficult to use correctly and none of the available examples mention that topic).

Here's what I ended up doing:

static bool IsAnyMouseButtonDown()
{
    ImGuiIO& io = ImGui::GetIO();
    for (int n = 0; n < ARRAYSIZE(io.MouseDown); n++)
        if (io.MouseDown[n])
            return true;
    return false;
}
    case WM_LBUTTONDOWN:
        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
        io.MouseDown[0] = true;
        return true;
    case WM_RBUTTONDOWN:
        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
        io.MouseDown[1] = true;
        return true;
    case WM_MBUTTONDOWN:
        if (!IsAnyMouseButtonDown()) ::SetCapture(hwnd);
        io.MouseDown[2] = true;
        return true;
    case WM_LBUTTONUP:
        io.MouseDown[0] = false;
        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
        return true;
    case WM_RBUTTONUP:
        io.MouseDown[1] = false;
        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
        return true;
    case WM_MBUTTONUP:
        io.MouseDown[2] = false;
        if (!IsAnyMouseButtonDown()) ::ReleaseCapture();
        return true;

Thanks again!

@heroboy
Copy link
Contributor

heroboy commented Oct 23, 2017

I think you should use GetCapture()

if (GetCapture() == NULL) SetCapture(hwnd);
if (GetCapture() == hwnd) ReleaseCapture();

Because if it is not caputed by the hwnd, it is not allowed to release the capture that is captued by the other window.

@Gargaj
Copy link
Contributor Author

Gargaj commented Oct 24, 2017

Yeah, I forgot about that ^^^ @ocornut

ocornut added a commit that referenced this pull request Oct 24, 2017
…1375)

ps: DirectX 12 example (#302) may want to adopt that as well.
@ocornut
Copy link
Owner

ocornut commented Oct 24, 2017

Fixed now, thanks!

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

Successfully merging this pull request may close these issues.

3 participants