The patch is only partially applied in the debugger branch.
I just update to rev 7362, but found that it's hard to apply the patch. So, I revert back to rev 7342, and apply the patch.
@obF:
cbEVT_EDITOR_TOOLTIP is sent from cbEditor to notify all the plugins, and which is cause by receiving the DWellStart event from scintilla control.
Connect( m_ID, -1, wxEVT_SCI_DWELLSTART,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnEditorDwellStart );
and
void cbEditor::OnEditorDwellStart(wxScintillaEvent& event)
{
if (!wxTheApp->IsActive())
return;
cbStyledTextCtrl* control = GetControl();
if (!control)
return;
wxRect screenRect = control->GetScreenRect();
wxPoint ptEvent(event.GetX(), event.GetY());
ptEvent = control->ClientToScreen(ptEvent);
wxPoint ptScreen = wxGetMousePosition();
wxPoint ptClient = control->ScreenToClient(ptScreen);
double distance = sqrt( (ptScreen.x - ptEvent.x) * (ptScreen.x - ptEvent.x)
+ (ptScreen.y - ptEvent.y) * (ptScreen.y - ptEvent.y) );
if (!screenRect.Contains(ptScreen) || distance > 10)
return;
int pos = control->PositionFromPoint(ptClient);
int style = control->GetStyleAt(pos);
NotifyPlugins(cbEVT_EDITOR_TOOLTIP, style, wxEmptyString, ptClient.x, ptClient.y);
wxScintillaEvent newEvent(event);
newEvent.SetX(ptClient.x);
newEvent.SetY(ptClient.y);
OnScintillaEvent(event);
}
and
void wxScintilla::NotifyParent (SCNotification* _scn)
{
SCNotification& scn = *_scn;
wxScintillaEvent evt (0, GetId());
evt.SetEventObject(this);
evt.SetPosition(scn.position);
evt.SetKey(scn.ch);
evt.SetModifiers(scn.modifiers);
switch (scn.nmhdr.code) {
case SCN_STYLENEEDED:
evt.SetEventType (wxEVT_SCI_STYLENEEDED);
break;
.......
.......
case SCN_DWELLSTART:
evt.SetEventType (wxEVT_SCI_DWELLSTART);
evt.SetX(scn.x);
evt.SetY(scn.y);
break;
the logic of sending SCN_DWELLSTART is much simple. in scintilla control, there is a timer, when the control received the MouseMove event, it will always restart the timer, if for about 500ms there is not MouseMove event happens, then the timer event handler will be fired, and send a
SCN_DWELLSTART event.
Any MouseMove or keypress will let restart the timer and send a
SCN_DWELLEND event.
Applying your patch, I see that both codecompletion plugin and debugger plugin will have a handler to response the cbEVT_EDITOR_TOOLTIP event from SDK, I found such code in debugger's handler:
void cbDebuggerPlugin::ProcessValueTooltip(CodeBlocksEvent& event)
{
event.Skip();
if (cbDebuggerCommonConfig::GetFlag(cbDebuggerCommonConfig::RequireCtrlForTooltips))
{
if (!wxGetKeyState(WXK_CONTROL))
return;
}
if (!ShowValueTooltip(event.GetInt()))
return;
EditorBase* base = event.GetEditor();
cbEditor* ed = base && base->IsBuiltinEditor() ? static_cast<cbEditor*>(base) : 0;
if (!ed)
return;
if (ed->IsContextMenuOpened())
return;
// get rid of other calltips (if any) [for example the code completion one, at this time we
// want the debugger value call/tool-tip to win and be shown]
if (ed->GetControl()->CallTipActive())
ed->GetControl()->CallTipCancel();
wxPoint pt;
pt.x = event.GetX();
pt.y = event.GetY();
const wxString &token = GetEditorWordAtCaret(&pt);
if (!token.empty())
{
pt = ed->GetControl()->ClientToScreen(pt);
OnValueTooltip(token, wxRect(pt.x - 5, pt.y, 10, 10));
}
}
This has the assumption that CC's handler is running before the debugger's handler. In-fact, there is no grantee which tip handler will run before other one. if CC's handler runs later, it will destroy the debugger's tip. This is a race condition.
we have discussed before.
also, this code:
if (cbDebuggerCommonConfig::GetFlag(cbDebuggerCommonConfig::RequireCtrlForTooltips))
{
if (!wxGetKeyState(WXK_CONTROL))
return;
}
Does not works under Windows for sure. I have exam this condition before. Under windows, if you hold the control key, then the timer in scintilla control will notice that your have press a key, and do a restart always, and the time handler never fired. (I'm not sure how the scintilla control was implemented under Linux), even though the SCN_DWELLSTART is already send, when detecting the ctrl key, it will quickly send a SCN_DWELLEND event to destroy the tip.
The other issue is related in my post:
DWELL Windows QuestionI can filter the ctrl key, so the sci control send SCN_DWELLSTART event does not consider the ctrl condition. the client has the duty to check whether show or disable the tip depend on the ctrl key condition. After your tip window is shown, if you still hold on the ctrl key. the tip window will received the key press event, and destroy the tip. at this condition, you need to filter the ctrl key event in the tip window too.