Author Topic: Anyone else getting selection artifacts when mouse selecting with left button?  (Read 7017 times)

Offline Robert Eastwood

  • Multiple posting newcomer
  • *
  • Posts: 13
It is because of some missed invalidation or message sequencing in Editor.cxx in the scintilla

I did a work around where I increased invalidation, still occured, so I added a redraw on left mouse button up handler, and that is good enough.

Then I added a flag set in problem areas, where artifacts apeared, and do a redraw if that bool is set in idleloop

And that gets rid of all the artifacts,

I also moved the part that slows down auto scrolling in buttondownwithmodifiers function to where it only skips that functionality and does not skip selection itself.

If anyone has an actual fix, has never seen the artifacts while selecting, or wants a cludgy fix, it isn't annoying when selecting on this build.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
What are the steps to reproduce this?
What do you mean by artefacts?
What OS? CB version? Wx version?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline Robert Eastwood

  • Multiple posting newcomer
  • *
  • Posts: 13
Really?   I can send a screen capture if you are interested in seeing the effect.


Using windows 10 mingw64 is the compiler I use,
Codeblocks 17.12 wxWidgets 3.12 64bit version

The selection error appears while selecting with left mouse down and moving mouse, and is quite noticable.
It is only a drawing issue because content in selection is correct when hitting copy or cut.  It also occurs for both multiple selections and single selection options.

There is a larger code change that does some other things such as condensing invalidation and redrawing from idle that is more efficient but simplier is better, and only added drawing overhead is when selecting multiple lines with mouse.

If you are not having the same issue you can ignore this post, although I have been using the latest released source code downloaded to build with, although I know there still are ways that the code base could be different for some reason.

If someone does have an issue where selection is not being redrawn correctly, this code change corrects that error I was experiencing.

it is in this function of Editor.cxx
void Editor::ButtonMoveWithModifiers(Point pt, int modifiers)


While selecting multiple lines the selection is correct but the drawing misses many invalidation.

(Also someone added a fix where 'when scrolling to fast while selecting lines' was fixed in an awkward way, it would slow down by skipping function always when selecting, even when not scrolling)

the fix to selection issue is to add these four lines, I did not indent them to show what lines are new.
It does add more drawing while dragging mouse to select lines, but the other option is to store the last mouse and make sure all old selection gets invalidated, and is more complex.
Since while line selecting other 'selection based' activities are mostly off, I just repaint when line selecting with mouse to fix it. 

The invalidate selection previously probably can be moved since irrelevant, but it solves the selection artifact items
Code
				if (sel.IsRectangular()) {
sel.Rectangular() = SelectionRange(movePos, sel.Rectangular().anchor);
SetSelection(movePos, sel.RangeMain().anchor);
RedrawRect(GetClientDrawingRectangle());//New Line Added
} else if (sel.Count() > 1) {
InvalidateSelection(sel.RangeMain(), false);
SelectionRange range(movePos, sel.RangeMain().anchor);
sel.TentativeSelection(range);
InvalidateSelection(range, true);
RedrawRect(GetClientDrawingRectangle());//New Line Added
} else {
SetSelection(movePos, sel.RangeMain().anchor);
RedrawRect(GetClientDrawingRectangle());//New Line Added
}
} else if (selectionType == selWord) {
// Continue selecting by word
if (movePos.Position() == wordSelectInitialCaretPos) {  // Didn't move
// No need to do anything. Previously this case was lumped
// in with "Moved forward", but that can be harmful in this
// case: a handler for the NotifyDoubleClick re-adjusts
// the selection for a fancier definition of "word" (for
// example, in Perl it is useful to include the leading
// '$', '%' or '@' on variables for word selection). In this
// the ButtonMove() called via Tick() for auto-scrolling
// could result in the fancier word selection adjustment
// being unmade.
} else {
wordSelectInitialCaretPos = -1;
WordSelection(movePos.Position());
}
} else {
// Continue selecting by line
RedrawRect(GetClientDrawingRectangle());//New Line Added
LineSelection(movePos.Position(), lineAnchorPos, selectionType == selWholeLine);
}
}


This part is just a different way, without slowing down selection, of doing auto scrolling.

Add this to Editor.h class as class members
Code
	int nautoScrollAmount;
int nautoScrollTotal;
//initialize them in constructor
Code
	nautoScrollAmount = 50;//slows down scrolling when selecting lines with mouse by 50% 100 is cpu speed, 20 would be 1/5 speed etc..
nautoScrollTotal = 0;
//comment out this code that previously skipped out of function even when not scrolling
Code
// Slow down autoscrolling/selection
/*autoScrollTimer.ticksToWait -= timer.tickSize;
if (autoScrollTimer.ticksToWait > 0)
{
return;
}
autoScrollTimer.ticksToWait = autoScrollDelay;*/
and then replace the old autoscroll code
Code
                // Autoscroll
int lineMove = DisplayFromPosition(movePos.Position());
if (pt.y > rcClient.bottom) {
ScrollTo(lineMove - LinesOnScreen() + 1);
Redraw();
} else if (pt.y < rcClient.top) {
ScrollTo(lineMove);
Redraw();
                }
                EnsureCaretVisible(false, false, true);
with where only auto scrolling is skipped if at less then 100%
by using this mechanism it only does its thing when scrolling while selecting, not everytime selecting
Code
                // Autoscroll
if(nautoScrollTotal > 99)//skip the scrolling till amount needed gets to over 99
{
int lineMove = DisplayFromPosition(movePos.Position());
if (pt.y > rcClient.bottom) {
//will allow for double or tripple scrolling speed if amount entered is 200 or 300
ScrollTo(lineMove - LinesOnScreen() + (nautoScrollTotal / 100));
Redraw();
} else if (pt.y < rcClient.top) {
//allows faster, but always at least 100 to get here, and always positive
ScrollTo(lineMove - ((nautoScrollTotal / 100) - 1));
Redraw();
}
nautoScrollTotal = 0;
}else{
nautoScrollTotal += nautoScrollAmount;
}
EnsureCaretVisible(false, false, true);



Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
I can send a screen capture if you are interested in seeing the effect.

Yes, do so, please.

Using windows 10 mingw64 is the compiler I use,
Codeblocks 17.12 wxWidgets 3.12 64bit version

17.12 is never tested with wx 3.1.2. Please test lastest master/trunk. Also trunk/master is using newer version of Scintilla (our editor component). There is not point playing/modifying the old version.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline Robert Eastwood

  • Multiple posting newcomer
  • *
  • Posts: 13

17.12 is never tested with wx 3.1.2. Please test lastest master/trunk. Also trunk/master is using newer version of Scintilla (our editor component). There is not point playing/modifying the old version.

I downloaded latest release source download, do you recommend downloading nightly build?

is that newer scintilla, or newer scintilla and newer editor?

using latest build you can see the artifacts by simply holding mouse down and moving mouse up and down.

Mostly it is two characters at line above, and occasionally a line to left of mouse below selection.

In this example I moved mouse up from between t and r in control = n line3214 then to line 3200 between e and t, then when I move mouse back down to line 3217 part of the previous selection remains where it should have been drawn over.  dragging another window overtop of it and then away repaints it and solves it so it is an invalidation issue.


Note I build original 17.12 Unicode 64bit using Mingw64 and wxWidgets 3.1.2  and it could be a Mingw64 issue, or even only windows issue, or anything else, it does not show up on 32bit build.

Here is the options set when building various .o files
For example when building Editor.cxx -o for scintilla

Build: scintilla in Code::Blocks wx3.1.x (compiler: GNU GCC Compiler(x64))
x86_64-w64-mingw32-g++.exe -Wall -std=c++1z -m64 "-O2" -pipe -mthreads -fmessage-length=0 -fexceptions -DHAVE_W32API_H -D__WXMSW__ -DWXUSINGDLL -DNOPCH -DwxUSE_UNICODE -D__WX__ -DWINVER=0x0501 -DLINK_LEXERS -DSCI_LEXER -DWXMAKINGDLL_SCI -std=c++1z -m64

Offline Robert Eastwood

  • Multiple posting newcomer
  • *
  • Posts: 13
17.12 is never tested with wx 3.1.2. Please test lastest master/trunk. Also trunk/master is using newer version of Scintilla (our editor component). There is not point playing/modifying the old version.

The function I mentioned changes for is still the same(although there were many changes elsewhere in the file),It should be noted how auto scroll while selecting is done can be added in, since old method still in use.  change in this thread is better since currently the function skips allowing the mouse to change selection half the time, making selection lag one mouse message behind often, and possibly missing a mouse move that is important.

I noticed many changes, and will test that file, it is possible someone found the error of invalidation for drawing somewhere else(since it was an invalidation error), however since the primary function called when selecting with mouse is still the same, I expect same results, but will look at it after building the 18.xx version, presuming that is the most current trunk.


Also could you tell me if the Scintilla.iface auto generation of wxScintilla is still the method used, and what app would generate the wxScinilla.h (2 files) needed from that file.  If I make changes that include adding messages to that file, I would like it to follow the current method used.   If you still use the Scintilla.iface could you quickly explain the generation method of files method.  If the Scintilla is simply copied by a bat to make sure values are the same for multiple compilation units that is a different method of updating.


Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13406
    • Travis build status
I can send a screen capture if you are interested in seeing the effect.

Yes, do so, please.

I'm ignoring your posts until you post a video of the problem...
Sorry, I'm too busy to read so much text.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline Robert Eastwood

  • Multiple posting newcomer
  • *
  • Posts: 13

I'm ignoring your posts until you post a video of the problem...
Sorry, I'm too busy to read so much text.
On the topic of Busy I added a deque FIFO buffer to cbEditor.

void cbEditor::OnScintillaEvent(wxScintillaEvent& event)
currently ignores events while loading or unloading projects.  Currently the events are simply lost during any state where ProjectManager::IsBusy()

Those events could be important so I added an event buffer so the events are not lost and are sent in the proper sequence after the busy state completes.

added to
void cbEditor::OnScintillaEvent(wxScintillaEvent& event)
Code
	//on busy loses events! when ProjectManager is busy (is loading a project or workspace, or unloading a project or workspace). 
        //This could create illogical sequencing.
//This code adds storing of events to be resent next time this function is called to send an event
       //and project manager is not busy, while maintaining event order.
if(EditorHooks::HasRegisteredHooks())
{
if(ProjectManager::IsBusy())
{
//events can't be sent, and we can't wait so buffer it
wxScintillaEvent* pevent = static_cast<wxScintillaEvent*>(event.Clone());
m_bufferedEvents.push_back(pevent);
}
else
{
//add busy check again in case one of the event is actually to load or unload a project
while(!m_bufferedEvents.empty() && !ProjectManager::IsBusy())
{
wxScintillaEvent* pEvent = m_bufferedEvents.front();
        m_bufferedEvents.pop_front();
        if(pEvent){
                    EditorHooks::CallHooks(this, *pEvent);//no recursion to not store events on stack
                    delete pEvent;
}

if(m_bufferedEvents.empty())//finished stored items
{
if(ProjectManager::IsBusy())
{
//another buffering because of busy again. could be recursive
wxScintillaEvent* peventnew = dynamic_cast<wxScintillaEvent*>(event.Clone());
m_bufferedEvents.push_back(peventnew);
}else
{
EditorHooks::CallHooks(this, event);
return;
}
}
}
}
}

in .h file
#include <deque>
std::deque<wxScintillaEvent*> m_bufferedEvents;

On the topic of your comment
I'm ignoring your posts until you post a video of the problem...
Sorry, I'm too busy to read so much text.
My post was intended to assist if you experience same issue, you ignoring this thread is fine with me.
if you do not want that assistance that is fine,

other people that build who may have seen the problem can choose to read and implement any changes that help them.

Your comment about wanting a video is a claim that you do not believe my comment. or that a video would be easier to understand
I have no reason to lie, nor to convince you,
although I may post a video next time I do a build without the various code changes that correct the issue.
possibly during looking at the newer code from 18xx trunk

Offline Robert Eastwood

  • Multiple posting newcomer
  • *
  • Posts: 13
Using snapshot of trunk to build based on latest code changes labeled as 11751  64bit build, mingw64 8.1, windows 10, wxWidgets 3.1.2 (with dx2d in wxWidgets build flag wxUSE_GRAPHICS_DIRECT2D set to 1 as is indicated as required)

The selection error does not occur.
Thanks for letting me know that using the latest version is far better then using the last official release 17.12 on codeblocks download page.

However the comment on changing the method of autoscrolling, to slow it down without slowing own selection while dragging mouse is still valid.
« Last Edit: June 28, 2019, 07:49:05 pm by Robert Eastwood »

Offline BlueHazzard

  • Developer
  • Lives here!
  • *****
  • Posts: 3352
Quote
Thanks for letting me know that using the latest version is far better then using the last official release 17.12 on codeblocks download page.
The trunk is 90% of the time the best version of cb we have... The least bugs and the most features. So if you build codeblocks by yourself you can mostly use the trunk version...