I don't know if this is helpful or not, but here's a patch to add a very rudimentary type of autocompletion to the wxWidgets stc sample. It doesn't show the crash under discussion, so it might not be helpful at all.
diff --git a/samples/stc/edit.cpp b/samples/stc/edit.cpp
index 7e7f412ec2..c16b1aae2b 100644
--- a/samples/stc/edit.cpp
+++ b/samples/stc/edit.cpp
@@ -60,6 +60,21 @@ const int ANNOTATION_STYLE = wxSTC_STYLE_LASTPREDEFINED + 1;
// Edit
//----------------------------------------------------------------------------
+static char * pound_xpm[] = {
+"10 10 2 1",
+" c None",
+". c #BD08F9",
+" .. .. ",
+" .. .. ",
+"..........",
+"..........",
+" .. .. ",
+" .. .. ",
+"..........",
+"..........",
+" .. .. ",
+" .. .. "};
+
wxBEGIN_EVENT_TABLE (Edit, wxStyledTextCtrl)
// common
EVT_SIZE ( Edit::OnSize)
@@ -177,6 +192,10 @@ Edit::Edit (wxWindow *parent, wxWindowID id,
CmdKeyClear (wxSTC_KEY_TAB, 0); // this is done by the menu accelerator key
SetLayoutCache (wxSTC_CACHE_PAGE);
UsePopUp(wxSTC_POPUP_ALL);
+
+ wxImage::AddHandler(new wxXPMHandler);
+ wxBitmap b(pound_xpm);
+ RegisterImage(0, b);
}
Edit::~Edit () {}
@@ -483,6 +502,13 @@ void Edit::OnCharAdded (wxStyledTextEvent &event) {
SetLineIndentation (currentLine, lineInd);
GotoPos(PositionFromLine (currentLine) + lineInd);
}
+ else if (chr == '#') {
+ wxString s = "define?0 elif?0 elifdef?0 elifndef?0 else?0 endif?0 "
+ "error?0 if?0 ifdef?0 ifndef?0 include?0 line?0 line?0 "
+ "pragma?0 undef?0";
+
+ AutoCompShow(0,s);
+ }
}
I don't know if this is helpful or not, but here's a patch to add a very rudimentary type of autocompletion to the wxWidgets stc sample. It doesn't show the crash under discussion, so it might not be helpful at all.
diff --git a/samples/stc/edit.cpp b/samples/stc/edit.cpp
index 7e7f412ec2..c16b1aae2b 100644
--- a/samples/stc/edit.cpp
+++ b/samples/stc/edit.cpp
@@ -60,6 +60,21 @@ const int ANNOTATION_STYLE = wxSTC_STYLE_LASTPREDEFINED + 1;
// Edit
//----------------------------------------------------------------------------
+static char * pound_xpm[] = {
+"10 10 2 1",
+" c None",
+". c #BD08F9",
+" .. .. ",
+" .. .. ",
+"..........",
+"..........",
+" .. .. ",
+" .. .. ",
+"..........",
+"..........",
+" .. .. ",
+" .. .. "};
+
wxBEGIN_EVENT_TABLE (Edit, wxStyledTextCtrl)
// common
EVT_SIZE ( Edit::OnSize)
@@ -177,6 +192,10 @@ Edit::Edit (wxWindow *parent, wxWindowID id,
CmdKeyClear (wxSTC_KEY_TAB, 0); // this is done by the menu accelerator key
SetLayoutCache (wxSTC_CACHE_PAGE);
UsePopUp(wxSTC_POPUP_ALL);
+
+ wxImage::AddHandler(new wxXPMHandler);
+ wxBitmap b(pound_xpm);
+ RegisterImage(0, b);
}
Edit::~Edit () {}
@@ -483,6 +502,13 @@ void Edit::OnCharAdded (wxStyledTextEvent &event) {
SetLineIndentation (currentLine, lineInd);
GotoPos(PositionFromLine (currentLine) + lineInd);
}
+ else if (chr == '#') {
+ wxString s = "define?0 elif?0 elifdef?0 elifndef?0 else?0 endif?0 "
+ "error?0 if?0 ifdef?0 ifndef?0 include?0 line?0 line?0 "
+ "pragma?0 undef?0";
+
+ AutoCompShow(0,s);
+ }
}
Hi, thanks for the contribution, I just test the stc sample with your patch.
The auto suggestion(auto completion) window shows correctly after I hit the "#", and I can keep typing in the editor, while the correct item is selected.
The issue I see is that if I "deactivate" the stcsample's main frame, the auto completion list is still active, which covers every active application's window. :(
The same effect can be achieved when we comment out the line:
void cbStyledTextCtrl::OnKillFocus(wxFocusEvent& event)
{
// cancel auto-completion list when losing focus
//if ( AutoCompActive() )
// AutoCompCancel();
if ( CallTipActive() )
CallTipCancel();
event.Skip();
}
With the above changes in sdk\cbstyledtextctrl.cpp, we can avoid the crash issue, but we get the same issue as the stc sample with your patch. :)
When debugging, I found the reason comes from this code flow:
void AutoComplete::Show(bool show) {
lb->Show(show); // set bp1 here
if (show)
lb->Select(0); // set bp2 here
}
When you try to show a autocompletion window, you first hit the bp1, then I see that a lose focus event happens before I hit the bp2, so the function
void cbStyledTextCtrl::OnKillFocus(wxFocusEvent& event)
{
// cancel auto-completion list when losing focus
if ( AutoCompActive() )
AutoCompCancel();
if ( CallTipActive() )
CallTipCancel();
event.Skip();
}
is called between bp1 and bp2.
Finally, when we goes to bp2, the window is already destroyed (wid==0). :(
@New Pagodi:
You can use this patch to reproduce the problem:
diff --git a/samples/stc/edit.cpp b/samples/stc/edit.cpp
index 855c18f..6a1c428 100644
--- a/samples/stc/edit.cpp
+++ b/samples/stc/edit.cpp
@@ -117,6 +117,7 @@ wxBEGIN_EVENT_TABLE (Edit, wxStyledTextCtrl)
EVT_STC_CHARADDED (wxID_ANY, Edit::OnCharAdded)
EVT_KEY_DOWN( Edit::OnKeyDown )
+ EVT_KILL_FOCUS(Edit::OnKillFocus)
wxEND_EVENT_TABLE()
Edit::Edit (wxWindow *parent, wxWindowID id,
@@ -472,6 +473,17 @@ void Edit::OnMarginClick (wxStyledTextEvent &event) {
}
}
+void Edit::OnKillFocus(wxFocusEvent& event)
+{
+ if ( AutoCompActive() )
+ AutoCompCancel();
+
+ if ( CallTipActive() )
+ CallTipCancel();
+
+ event.Skip();
+}
+
void Edit::OnCharAdded (wxStyledTextEvent &event) {
char chr = (char)event.GetKey();
int currentLine = GetCurrentLine();
@@ -485,6 +497,21 @@ void Edit::OnCharAdded (wxStyledTextEvent &event) {
SetLineIndentation (currentLine, lineInd);
GotoPos(PositionFromLine (currentLine) + lineInd);
}
+ else
+ {
+ wxString items;
+ items += "test1\r";
+ items += "test2\r";
+ items += "test3\r";
+ items += "test4\r";
+ items += "test5\r";
+
+ AutoCompSetIgnoreCase(true);
+ AutoCompSetMaxHeight(14);
+ AutoCompSetTypeSeparator(wxT('\n'));
+ AutoCompSetSeparator(wxT('\r'));
+ AutoCompShow(0, items);
+ }
}
diff --git a/samples/stc/edit.h b/samples/stc/edit.h
index 703ebae..2762a85 100644
--- a/samples/stc/edit.h
+++ b/samples/stc/edit.h
@@ -107,6 +107,7 @@ public:
void OnCharAdded (wxStyledTextEvent &event);
void OnKeyDown(wxKeyEvent &event);
+ void OnKillFocus(wxFocusEvent& event);
//! language/lexer
wxString DeterminePrefs (const wxString &filename);
I've started a thread on the problems with autocompletion on the wxdev list here (https://groups.google.com/forum/#!topic/wx-dev/R--2avQzHdo) if anyone wants to join in.
But I guess none of those changes proposed there will help with with getting codeblocks to work with wxWidgets 3.1.2. In order to do that, somehow the old popup behavior has to be restored in codeblocks itself - at least until 3.1.3. Looking over the codeblocks sources, I think the easiest way to do that is to define a popup class in src/sdk/wxscintilla/src/PlatWX.cpp between
#if wxUSE_POPUPWIN //-----------------------------------
#include "wx/popupwin.h"
and
// A popup window to place the wxSCIListBox upon
class wxSCIListBoxWin : public wxPopupWindow
Here's the a cut and paste of the old popupwindow code with a few minor modifications:
#ifdef __WXMSW__
#include "wx/msw/private.h" // for GetDesktopWindow()
class wxNonActivatingPopupWindow : public wxPopupWindowBase
{
public:
wxNonActivatingPopupWindow() { }
wxNonActivatingPopupWindow(wxWindow *parent, int flags = wxBORDER_NONE)
{ (void)Create(parent, flags); }
bool Create(wxWindow *parent, int flags = wxBORDER_NONE);
virtual void SetFocus() wxOVERRIDE;
virtual bool Show(bool show = true) wxOVERRIDE;
// return the style to be used for the popup windows
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const wxOVERRIDE;
// get the HWND to be used as parent of this window with CreateWindow()
virtual WXHWND MSWGetParent() const wxOVERRIDE;
};
bool wxNonActivatingPopupWindow::Create(wxWindow *parent, int flags)
{
// popup windows are created hidden by default
Hide();
return wxPopupWindowBase::Create(parent) &&
wxWindow::Create(parent, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
flags | wxPOPUP_WINDOW);
}
WXDWORD wxNonActivatingPopupWindow::MSWGetStyle(long flags, WXDWORD *exstyle) const
{
// we only honour the border flags, the others don't make sense for us
WXDWORD style = wxWindow::MSWGetStyle(flags & wxBORDER_MASK, exstyle);
if ( exstyle )
{
// a popup window floats on top of everything
*exstyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
}
return style;
}
WXHWND wxNonActivatingPopupWindow::MSWGetParent() const
{
// we must be a child of the desktop to be able to extend beyond the parent
// window client area (like the comboboxes drop downs do)
//
// NB: alternative implementation would be to use WS_POPUP instead of
// WS_CHILD but then showing a popup would deactivate the parent which
// is ugly and working around this, although possible, is even more
// ugly
return (WXHWND)::GetDesktopWindow();
}
void wxNonActivatingPopupWindow::SetFocus()
{
// Focusing on a popup window does not work on MSW unless WS_POPUP style is
// set (which is never the case currently, see the note in MSWGetParent()).
// We do not even want to try to set the focus, as it returns an error from
// SetFocus() on recent Windows versions (since Vista) and the resulting
// debug message is annoying.
}
bool wxNonActivatingPopupWindow::Show(bool show)
{
if ( !wxWindowMSW::Show(show) )
return false;
if ( show )
{
// raise to top of z order
if (!::SetWindowPos((HWND)GetHWND(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE))
{
wxLogLastError(wxT("SetWindowPos"));
}
// and set it as the foreground window so the mouse can be captured
::SetForegroundWindow((HWND)GetHWND());
}
return true;
}
// temporarily define wxPopupWindow to be the new class
#define wxPopupWindow wxNonActivatingPopupWindow
#endif //__WXMSW__
The class can obviously be renames as needed. I've tested this with wxSTC, but I don't know how to compile codeblocks to see if it works there too.
I'm using C::B with New Pagodi's patch and CC works OK, but sometimes the caret disappears while editing: you can't see it, but typing works normally. The only way to make it visible again is changing focus to another window and then to the current window.
If I disable CC this does not happen. I can't test without the patch because C:B crashes.
Using Windows 7 64 bits, wx3.1.2 32 bits, revision 11552.
I can confirm this issue.
EDIT: it looks like this issue happens when I hover the mouse on some variable, which means it's a calltip related issue.
Also, when this issue happens, the high light of the current line is also missing.
My guess here is that we have such code in sdk\ccmanager.cpp
//{ Unfocusable popup
// imported with small changes from PlatWX.cpp
class UnfocusablePopupWindow :
#if wxUSE_POPUPWIN
public wxPopupWindow
#else
public wxFrame
#endif // wxUSE_POPUPWIN
{
public:
#if wxUSE_POPUPWIN
typedef wxPopupWindow BaseClass;
UnfocusablePopupWindow(wxWindow* parent, int style = wxBORDER_NONE) :
wxPopupWindow(parent, style)
#else
typedef wxFrame BaseClass;
UnfocusablePopupWindow(wxWindow* parent, int style = 0) :
wxFrame(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
style | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT | wxNO_BORDER | wxFRAME_SHAPED
#ifdef __WXMAC__
| wxPOPUP_WINDOW
#endif // __WXMAC__
)
#endif // wxUSE_POPUPWIN
{
Hide();
}
bool Destroy() override;
void OnFocus(wxFocusEvent& event);
void ActivateParent();
void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO) override;
bool Show(bool show = true) override;
private:
DECLARE_EVENT_TABLE()
};
This means we need to use the same wxNonActivatingPopupWindow class as New Pagodi's patch?
If devs choose patching wxWidgets 3.1.2 to solve CC crashes I suggest adding this code (or similar) somewhere so people compiling from SVN in MSW with 3.1.2 know what to do.
#if wxUSE_POPUPWIN && defined(__WXMSW__) && wxVERSION_NUMBER == 3102
#include "wx/popupwin.h"
#ifndef wxPU_CONTAINS_CONTROLS
#error wxWidgets 3.1.2 must be patched or CC will crash
#endif
#endif