On Sun, May 15, 2005 at 07:11:02PM +0200, Helge Hafting wrote:
> On Sun, May 15, 2005 at 05:09:39PM +0300, Martin Vermeer wrote:
> > Lars,
> > 
> > Now that I have had some time to think it over, I am more and more
> > inclined to suspect that there is something to my dark fear.
> > 
> > As I understand it, LyX, Qt and X all process events in a "linear"
> > fashion. This means, that routines call subroutines (stacking their
> > context), calling subroutines, etc... until they return and unwind their
> > contexts. 
> > 
> > The event loop (X or Qt) is no different.
> > 
> > Under such a scheme it is _in principle impossible_ for function calls
> > in different places in the code to pre-empt each other. The keystroke
> > reversal we saw just cannot come about.
> > 
> > So, _something_ is happening non-linearly, through pre-emption. We know
> > of course that this kind of thing is happening on the system level all
> > the time (hardware clock interrupt etc., process/thread switching). But
> > this is irrelevant for our problem. It would be surprising if the same
> > happened inside LyX.

...
 
> > qt-mt, doesn't that mean Qt multi-threading? Or am I holding the wrong
> > end of the stick?
> 
> Yes, it means multithreading.  However, I wouldn't suspect it of magially
> starting to multithread an application.  I always thought that qt-mt merely
> supported multithreading - i.e. qt-mt won't mysteriously break *if*
> your program is multithreaded, but qt(non-mt) may show some
> very strange errors with a multithreaded program.
> 
> I don't know qt very well, but this is how mt- and non-mt versions
> of other libraries tend to work.  An mt-version is multithread-safe,
> while the non-mt version is either older or uses some optimizations
> that won't work in a multithreaded environment.  An mt-version
> will be thread-safe in that everything either is reentrant code, or
> use some sort of semaphore to protect anything that isn't 
> automatically thread-safe.
> 
> Helge Hafting

Yes Helge and Andre, I must agree.

I did some more reading up yesterday and now I believe it is the call to
processEvents which is handled pre-emptively, probably by calling some
system routine. In the article I read (which I don't find now) it is
pointed out that there are two ways to make the UI update during a long
operation:

1) use a QTimer (requiring the long operation to be cut into small
pieces): this is co-operative multitasking.

2) Using processEvents: apparently pre-emptive.

We are doing both, getting us into the mess we're in.

Give the attached proof-of-concept code a try. Upon repeat page down on 
the Users' Guide it behaves quite differently from what I believe we have
been striving for, but more like I think an X app should behave: it
coalesces drawing events. Takes some getting used to perhaps.

Leaving for the field in an hour...

- Martin

PS the patch may not be quite clean because of other stuff I have in my
tree.

Index: BufferView_pimpl.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v
retrieving revision 1.583
diff -u -p -r1.583 BufferView_pimpl.C
--- BufferView_pimpl.C  11 May 2005 07:44:18 -0000      1.583
+++ BufferView_pimpl.C  16 May 2005 04:56:23 -0000
@@ -644,6 +646,7 @@ void BufferView::Pimpl::update(bool fitc
                        // Abort updating of the coord
                        // cache - just restore the old one
                        std::swap(theCoords, backup);
+                       screen().allowSync();
                }
        } else
                screen().greyOut();
Index: frontends/screen.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/screen.C,v
retrieving revision 1.102
diff -u -p -r1.102 screen.C
--- frontends/screen.C  11 May 2005 07:44:19 -0000      1.102
+++ frontends/screen.C  16 May 2005 04:56:23 -0000
@@ -158,8 +158,10 @@ void LyXScreen::showCursor(BufferView & 
        // guard is set/cleared which is used here to prevent recursive
        // calls to screen update. startUpdating() and doneUpdating() in
        // coordcache again contain asserts to detect such recursion.
-       if (sync_allowed_)
-               lyx_gui::sync_events();
+       //if (sync_allowed_)
+       //      lyx_gui::sync_events();
+       if (!sync_allowed_)
+               cursor_visible_ = true;
 
        if (cursor_visible_)
                return;
@@ -206,8 +208,10 @@ void LyXScreen::showCursor(BufferView & 
 
 void LyXScreen::hideCursor()
 {
-       if (sync_allowed_)
-               lyx_gui::sync_events();
+       //if (sync_allowed_)
+       //      lyx_gui::sync_events();
+       if (!sync_allowed_)
+               cursor_visible_ = false;
 
        if (!cursor_visible_)
                return;
Index: frontends/screen.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/screen.h,v
retrieving revision 1.31
diff -u -p -r1.31 screen.h
--- frontends/screen.h  11 May 2005 07:44:19 -0000      1.31
+++ frontends/screen.h  16 May 2005 04:56:23 -0000
@@ -56,6 +56,8 @@ public:
 
        ///
        void unAllowSync() { sync_allowed_ = false; };
+       ///
+       void allowSync() { sync_allowed_ = true; };
 
 protected:
        /// cause the display of the given area of the work area

Attachment: pgprlKNJTAcV2.pgp
Description: PGP signature

Reply via email to