mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 00:47:34 +08:00
Handle context-help mouse capture loss
End wxContextHelp mode when mouse capture is lost and only release the mouse if the help window still owns capture after the modal help loop. Add coverage for the capture-loss path so context help exits without using another input event. Fixes #21534. Closes #26674.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
// Author: Julian Smart, Vadim Zeitlin
|
||||
// Created: 08/09/2000
|
||||
// Copyright: (c) 2000 Julian Smart, Vadim Zeitlin
|
||||
// (c) 2026 wxWidgets development team
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -108,7 +109,8 @@ bool wxContextHelp::BeginContextHelp(wxWindow* win)
|
||||
|
||||
EventLoop();
|
||||
|
||||
win->ReleaseMouse();
|
||||
if ( win->HasCapture() )
|
||||
win->ReleaseMouse();
|
||||
|
||||
win->PopEventHandler(true);
|
||||
|
||||
@@ -173,10 +175,11 @@ bool wxContextHelpEvtHandler::ProcessEvent(wxEvent& event)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((event.GetEventType() == wxEVT_CHAR) ||
|
||||
(event.GetEventType() == wxEVT_KEY_DOWN) ||
|
||||
(event.GetEventType() == wxEVT_ACTIVATE) ||
|
||||
(event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED))
|
||||
if ( (event.GetEventType() == wxEVT_CHAR) ||
|
||||
(event.GetEventType() == wxEVT_KEY_DOWN) ||
|
||||
(event.GetEventType() == wxEVT_ACTIVATE) ||
|
||||
(event.GetEventType() == wxEVT_MOUSE_CAPTURE_CHANGED) ||
|
||||
(event.GetEventType() == wxEVT_MOUSE_CAPTURE_LOST) )
|
||||
{
|
||||
// May have already been set to true by a left-click
|
||||
//m_contextHelp->SetStatus(false);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// Author: Steven Lamerton
|
||||
// Created: 2010-07-10
|
||||
// Copyright: (c) 2010 Steven Lamerton
|
||||
// (c) 2026 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "testprec.h"
|
||||
@@ -25,6 +26,7 @@
|
||||
#include "wx/caret.h"
|
||||
#include "wx/cshelp.h"
|
||||
#include "wx/dcclient.h"
|
||||
#include "wx/timer.h"
|
||||
#include "wx/tooltip.h"
|
||||
#include "wx/wupdlock.h"
|
||||
|
||||
@@ -55,6 +57,78 @@ protected:
|
||||
wxDECLARE_NO_COPY_CLASS(WindowTestCase);
|
||||
};
|
||||
|
||||
#if wxUSE_HELP
|
||||
class ContextHelpCaptureLostTester : public wxWindow
|
||||
{
|
||||
public:
|
||||
ContextHelpCaptureLostTester(wxWindow* parent)
|
||||
: wxWindow(parent, wxID_ANY)
|
||||
{
|
||||
}
|
||||
|
||||
void SimulateCaptureLost()
|
||||
{
|
||||
DoReleaseMouse();
|
||||
NotifyCaptureLost();
|
||||
}
|
||||
};
|
||||
|
||||
class ContextHelpCaptureLostState : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
explicit ContextHelpCaptureLostState(ContextHelpCaptureLostTester* win)
|
||||
: m_win(win),
|
||||
m_captureLostTimer(this),
|
||||
m_fallbackTimer(this)
|
||||
{
|
||||
Bind(wxEVT_TIMER, &ContextHelpCaptureLostState::OnTimer, this);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_captureLostTimer.StartOnce(1);
|
||||
}
|
||||
|
||||
void Done()
|
||||
{
|
||||
m_done = true;
|
||||
m_captureLostTimer.Stop();
|
||||
m_fallbackTimer.Stop();
|
||||
}
|
||||
|
||||
bool WasCaptureLostSent() const { return m_captureLostSent; }
|
||||
bool WasFallbackUsed() const { return m_fallbackUsed; }
|
||||
|
||||
private:
|
||||
void OnTimer(wxTimerEvent& event)
|
||||
{
|
||||
if ( m_done )
|
||||
return;
|
||||
|
||||
if ( &event.GetTimer() == &m_captureLostTimer )
|
||||
{
|
||||
m_captureLostSent = true;
|
||||
m_win->SimulateCaptureLost();
|
||||
m_fallbackTimer.StartOnce(100);
|
||||
return;
|
||||
}
|
||||
|
||||
m_fallbackUsed = true;
|
||||
|
||||
wxKeyEvent eventKey(wxEVT_KEY_DOWN);
|
||||
eventKey.SetEventObject(m_win);
|
||||
m_win->GetEventHandler()->ProcessEvent(eventKey);
|
||||
}
|
||||
|
||||
ContextHelpCaptureLostTester* const m_win;
|
||||
wxTimer m_captureLostTimer;
|
||||
wxTimer m_fallbackTimer;
|
||||
bool m_done = false;
|
||||
bool m_captureLostSent = false;
|
||||
bool m_fallbackUsed = false;
|
||||
};
|
||||
#endif // wxUSE_HELP
|
||||
|
||||
static void DoTestShowHideEvent(wxWindow* window)
|
||||
{
|
||||
EventCounter show(window, wxEVT_SHOW);
|
||||
@@ -179,6 +253,26 @@ TEST_CASE_METHOD(WindowTestCase, "Window::Mouse", "[window]")
|
||||
CHECK(!m_window->HasCapture());
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(WindowTestCase, "Window::ContextHelpCaptureLost",
|
||||
"[window][help]")
|
||||
{
|
||||
#if wxUSE_HELP
|
||||
ContextHelpCaptureLostTester* const win =
|
||||
new ContextHelpCaptureLostTester(wxTheApp->GetTopWindow());
|
||||
ContextHelpCaptureLostState state(win);
|
||||
state.Start();
|
||||
|
||||
wxContextHelp contextHelp(win, false);
|
||||
|
||||
CHECK(contextHelp.BeginContextHelp(win));
|
||||
|
||||
state.Done();
|
||||
CHECK(state.WasCaptureLostSent());
|
||||
CHECK(!state.WasFallbackUsed());
|
||||
CHECK(!win->HasCapture());
|
||||
#endif // wxUSE_HELP
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(WindowTestCase, "Window::Properties", "[window]")
|
||||
{
|
||||
m_window->SetLabel("label");
|
||||
|
||||
Reference in New Issue
Block a user