nested updates

2005-05-08 Thread Andre Poenitz


To our local Qt professionals:

Why do we need

[EMAIL PROTECTED]:/usr/src/lyx/lyx-devel/src > grep -R processEve *
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QMathDialog.C:qApp->processEvents();
frontends/qt2/QMathDialog.C:qApp->processEvents();
frontends/qt2/lyx_gui.C:qApp->processEvents();
frontends/qt2/QLPopupMenu.C:qApp->processEvents();

One of these seems to be the cause of nested update() calls...

Andre'


Re: nested updates

2005-05-08 Thread Asger Ottar Alstrup
Andre Poenitz wrote:
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QMathDialog.C:qApp->processEvents();
frontends/qt2/QMathDialog.C:qApp->processEvents();
frontends/qt2/lyx_gui.C:qApp->processEvents();
frontends/qt2/QLPopupMenu.C:qApp->processEvents();
Take then out, and see what happens... I believe this is a fundamental 
problem. It does not make sense to update while updating.

If it doesn't work without these processEvents, then the dispatcher 
should queue lyx func requests up, and handle them when the update is 
completely.

Also, the updater can be extended to abort when the coord cache is full, 
before drawing, if a pending update is in the queue.

Regards,
Asger


Re: nested updates

2005-05-08 Thread Asger Ottar Alstrup
Asger Ottar Alstrup wrote:
Andre Poenitz wrote:
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QDialogView.h:qApp->processEvents();
frontends/qt2/QMathDialog.C:qApp->processEvents();
frontends/qt2/QMathDialog.C:qApp->processEvents();
frontends/qt2/lyx_gui.C:qApp->processEvents();
frontends/qt2/QLPopupMenu.C:qApp->processEvents();
If it doesn't work without these processEvents, then the dispatcher 
should queue lyx func requests up, and handle them when the update is 
completely.
Thinking about this a bit more: An alternative approach is to flag that 
we need to postpone the processEvents() calls after the update. Replace 
the calls above with a call to a function that does:

  if (updating) {
needProcessEvent = true;
  } else {
qApp->processEvents();
  }
and at the bottom of update, do:
  while (needProcessEvent) {
needProcessEvent = false;
qApp->processEvents();
  }
Assuming that the nested updates come from processEvent, this approach 
solves the problem by delaying the processEvent just enough to be able 
to handle it. It is simpler to implement than queing of lyx funcs, and 
it is also more general, since some of the problematic things might not 
be lyx funcs.

Also, I think there is less of a risk of infinite loops this way.
Regards,
Asger


Re: [Patch] Table crash blues

2005-05-08 Thread Andre Poenitz
On Sat, May 07, 2005 at 09:21:20PM +0100, Angus Leeming wrote:
> Andre Poenitz wrote:
> > [Actually, there seems to be some bad Qt GUI interaction involved as the
> > problem shows only up when having certain dialogs open. Otherwise, plain
> > full redraw seems to be fast enough...]
> 
> You reckon it's fast enough? 14x is *much* slower than 13x when using over
> an ADSL line.

I haven't tried that, but local xform is certainly usably very well
speed-wise.

We could save some network traffic by restricting actual drawing to some
horizontal strip as we did in 1.3, but this would be new code, the old
logic does not fit anymore.

Andre'


Re: [Patch] Table crash blues

2005-05-08 Thread Andre Poenitz
On Sat, May 07, 2005 at 11:23:03PM +0200, Helge Hafting wrote:
> > > Coarse screen updates when the cpu can't keep up is much better
> > > than detailed but lagging updates.  
> > 
> > And our real problem is that our updates do not serve only the
> > purpose of showing something on screen, but also to put the
> > coordcache in some sensible state. This can't be skipped if we
> > expect e.g.  to work even while typing fast.
> 
> I see.  The coord cache must be updated, but I hope the actual drawing
> can be skipped ??? when lyx knows that it is behind.  That improves
> performance in many cases, such as an overloaded machine or X over a
> slow network.

The coord cache is filled in the drawing phase (the metrics phase fills
the size part of the coord cache only). We _do_ have a 'null painter'
which only fills the cache, but if we did metrics + null painter
painting + real painting in every case, drawing might get slow. Just a
suspicion, though.

Andre'


Re: [Patch] Table crash blues

2005-05-08 Thread Michael Schmitt
Andre Poenitz wrote:
I see.  The coord cache must be updated, but I hope the actual drawing
can be skipped ??? when lyx knows that it is behind.  That improves
performance in many cases, such as an overloaded machine or X over a
slow network.
   

The coord cache is filled in the drawing phase (the metrics phase fills
the size part of the coord cache only). We _do_ have a 'null painter'
which only fills the cache, but if we did metrics + null painter
painting + real painting in every case, drawing might get slow. Just a
suspicion, though.
 

Hmmm, I would have expected that the only expensive operations is the 
real painting (provided that the null painter does not invoke any X/Qt 
methods). Is it possible to combine metrics & null painter?

Without knowing the details, I think the only clean solution is to avoid 
recursive/reentrant updates completely. I always prefer stability over 
performance.

Michael


Re: [Patch] Table crash blues

2005-05-08 Thread Asger Ottar Alstrup
Andre Poenitz wrote:
The coord cache is filled in the drawing phase (the metrics phase fills
the size part of the coord cache only). We _do_ have a 'null painter'
which only fills the cache, but if we did metrics + null painter
painting + real painting in every case, drawing might get slow. Just a
suspicion, though.
An idea to fix the update over ADSL in a general way, in a way which 
does not require the kernel to know about the extend a change has on the 
screen:

The null painting phase can be used to detect what really needs to be 
updated.

During an update, we built a fingerprint hash of each painting 
operation: a hash based on the content and the operation itself. This 
finger-print is stored in a data-structure indexed by the rectangle the 
operation covers.

So, each update results in a set of fingerprints, which exactly describe 
what was drawn at each pixel on the screen: All pixels in the affected 
rectangle has that hash associated.

Now we need to update the screen, because something changed. First, we 
draw with the null-painter. For each operation, we also calculate the 
fingerprint and rectangles like above.

So, now we have two data-structures of rectangles with their associated 
fingerprints. We compare the old and the new entires. All the different 
entries tell us what really needs to be updated. Thus, we build a set of 
rectangles which tell us what parts of the screen really needs an update.

Then we fill these parts of the screen with the background color.
Next, we start the second drawing phase with a real painter: For all 
requests, we check whether we intersect a rectangle which needs an 
update. If not, we just skip it. If we do, we do the drawing as requested.

Regards,
Asger


Re: unneeded update() calls

2005-05-08 Thread Georg Baum
Am Samstag, 7. Mai 2005 21:35 schrieb Andre Poenitz:
> 
> Could anybody please make sure that 'his' code does not contain
> unnecessary update() calls?
> 
> As a first approximation I'd classify any update() with exception
> of the one in lyxfunc.C as 'unnecessary'.
> 
> Most notably the LFUN_INSET_MODIFY handling seems to have sneaked
> something in...

All update() calls in src/insets are unnecessary. They are all in 
do_dispatch(), and LCursor->dispatch() makes sure that update is called.
It is the other way round: We need to call cur.noUpdate() if no update is 
needed.
I did also call noUpdate() instead of undispatched() in insetcommand.C. Is 
that correct?


Georg
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetcommand.C lyx-1.4-cvs/src/insets/insetcommand.C
--- lyx-1.4-clean/src/insets/insetcommand.C	2005-04-23 10:15:05.0 +0200
+++ lyx-1.4-cvs/src/insets/insetcommand.C	2005-05-08 10:47:07.0 +0200
@@ -109,12 +109,10 @@ void InsetCommand::doDispatch(LCursor & 
 	case LFUN_INSET_MODIFY: {
 		InsetCommandParams p;
 		InsetCommandMailer::string2params(mailer_name_, cmd.argument, p);
-		if (p.getCmdName().empty()) {
-			cur.undispatched();
-		} else {
+		if (p.getCmdName().empty())
+			cur.noUpdate();
+		else
 			setParams(p);
-			cur.bv().update();
-		}
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetfloat.C lyx-1.4-cvs/src/insets/insetfloat.C
--- lyx-1.4-clean/src/insets/insetfloat.C	2005-04-23 10:15:08.0 +0200
+++ lyx-1.4-cvs/src/insets/insetfloat.C	2005-05-08 10:44:43.0 +0200
@@ -160,7 +160,6 @@ void InsetFloat::doDispatch(LCursor & cu
 		params_.sideways  = params.sideways;
 		wide(params_.wide, cur.buffer().params());
 		sideways(params_.sideways, cur.buffer().params());
-		cur.bv().update();
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetgraphics.C lyx-1.4-cvs/src/insets/insetgraphics.C
--- lyx-1.4-clean/src/insets/insetgraphics.C	2005-04-23 10:15:08.0 +0200
+++ lyx-1.4-cvs/src/insets/insetgraphics.C	2005-05-08 10:43:21.0 +0200
@@ -197,10 +206,10 @@ void InsetGraphics::doDispatch(LCursor &
 		Buffer const & buffer = cur.buffer();
 		InsetGraphicsParams p;
 		InsetGraphicsMailer::string2params(cmd.argument, buffer, p);
-		if (!p.filename.empty()) {
+		if (!p.filename.empty())
 			setParams(p);
-			cur.bv().update();
-		}
+		else
+			cur.noUpdate();
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetinclude.C lyx-1.4-cvs/src/insets/insetinclude.C
--- lyx-1.4-clean/src/insets/insetinclude.C	2005-04-23 10:15:17.0 +0200
+++ lyx-1.4-cvs/src/insets/insetinclude.C	2005-05-08 10:43:57.0 +0200
@@ -128,10 +153,10 @@ void InsetInclude::doDispatch(LCursor & 
 	case LFUN_INSET_MODIFY: {
 		InsetCommandParams p;
 		InsetIncludeMailer::string2params(cmd.argument, p);
-		if (!p.getCmdName().empty()) {
+		if (!p.getCmdName().empty())
 			set(p, cur.buffer());
-			cur.bv().update();
-		}
+		else
+			cur.noUpdate();
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetnote.C lyx-1.4-cvs/src/insets/insetnote.C
--- lyx-1.4-clean/src/insets/insetnote.C	2005-04-23 10:15:17.0 +0200
+++ lyx-1.4-cvs/src/insets/insetnote.C	2005-05-08 10:45:43.0 +0200
@@ -192,7 +192,6 @@ void InsetNote::doDispatch(LCursor & cur
 	case LFUN_INSET_MODIFY:
 		InsetNoteMailer::string2params(cmd.argument, params_);
 		setButtonLabel();
-		cur.bv().update();
 		break;
 
 	case LFUN_INSET_DIALOG_UPDATE:
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetwrap.C lyx-1.4-cvs/src/insets/insetwrap.C
--- lyx-1.4-clean/src/insets/insetwrap.C	2005-04-23 10:15:17.0 +0200
+++ lyx-1.4-cvs/src/insets/insetwrap.C	2005-05-08 10:45:51.0 +0200
@@ -83,7 +83,6 @@ void InsetWrap::doDispatch(LCursor & cur
 		InsetWrapMailer::string2params(cmd.argument, params);
 		params_.placement = params.placement;
 		params_.width = params.width;
-		cur.bv().update();
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/updatableinset.C lyx-1.4-cvs/src/insets/updatableinset.C
--- lyx-1.4-clean/src/insets/updatableinset.C	2005-02-01 20:16:20.0 +0100
+++ lyx-1.4-cvs/src/insets/updatableinset.C	2005-05-08 10:44:22.0 +0200
@@ -99,8 +99,8 @@ void UpdatableInset::doDispatch(LCursor 
 scroll(cur.bv(), static_cast(convert(cmd.argument)));
 			else
 scroll(cur.bv(), convert(cmd.argument));
-			cur.bv().update();
-		}
+		} else
+			cur.noUpdate();
 		break;
 
 	default:


Re: unneeded update() calls

2005-05-08 Thread Asger Ottar Alstrup
Georg Baum wrote:
All update() calls in src/insets are unnecessary. They are all in 
do_dispatch(), and LCursor->dispatch() makes sure that update is called.
It is the other way round: We need to call cur.noUpdate() if no update is 
needed.
I did also call noUpdate() instead of undispatched() in insetcommand.C. Is 
that correct?
Looks right to me.
Maybe you could add some comments about what the protocol for 
update/noupdate calls is? Add it to the BufferView::update method, or 
wherever the main update call is.

In general, I think the new code should be commented some more. Maybe 
you do not understand exactly how it is supposed to work, but it is 
still better to add a comment about how you understand it than not 
adding something. Then, the people that understand it can post patches 
to the comments.

Regards,
Asger


Re: [Patch] Table crash blues

2005-05-08 Thread Michael Schmitt
Asger Ottar Alstrup wrote:
Andre Poenitz wrote:
The coord cache is filled in the drawing phase (the metrics phase fills
the size part of the coord cache only). We _do_ have a 'null painter'
which only fills the cache, but if we did metrics + null painter
painting + real painting in every case, drawing might get slow. Just a
suspicion, though.
An idea to fix the update over ADSL in a general way, in a way which 
does not require the kernel to know about the extend a change has on 
the screen:

The null painting phase can be used to detect what really needs to be 
updated.

During an update, we built a fingerprint hash of each painting 
operation: a hash based on the content and the operation itself. This 
finger-print is stored in a data-structure indexed by the rectangle 
the operation covers.
IMHO all this falls into category "optimization". It's nice to think 
about it but first the real problem has to be solved. My impression - 
from a perspective of guy who knows nothing about the details - the 
additional null painter step looks reasonable.

Regards, Michael


Re: [Patch] Table crash blues

2005-05-08 Thread Asger Ottar Alstrup
Michael Schmitt wrote:
IMHO all this falls into category "optimization". It's nice to think 
about it but first the real problem has to be solved. My impression - 
from a perspective of guy who knows nothing about the details - the 
additional null painter step looks reasonable.
For sure it is an optimisation, but it might be justified since it is a 
severe regression compared to 1.3.

Also, notice the null painter step in itself will not solve the crashes. 
Introducing it to avoid excessive repaints due to nested update calls is 
only a band-aid.

A better fix is to go to the root of the cause, and in this case, as 
mentioned in another post, I believe the right fix is to either omit or 
postpone the qApps->processEvent calls during update.

Of course, excessive update calls from other places, as found by George, 
should also be nailed. (Notice, that the optimisation as sketched out 
would reduce the cost of superfluous update calls to a metrics and 
null-paint job only - the outcome would be identical to before, and no 
painting on screen would be necessary).

Regards,
Asger


Re: [Patch] Table crash blues

2005-05-08 Thread Michael Schmitt
Asger Ottar Alstrup wrote:
A better fix is to go to the root of the cause, and in this case, as 
mentioned in another post, I believe the right fix is to either omit 
or postpone the qApps->processEvent calls during update.

Of course, excessive update calls from other places, as found by 
George, should also be nailed. (Notice, that the optimisation as 
sketched out would reduce the cost of superfluous update calls to a 
metrics and null-paint job only - the outcome would be identical to 
before, and no painting on screen would be necessary).
So the "best" solution would be:
1. Run metrics computation & null painter as a single 
non-interruptable, non-reentrant step
(There should be some assertions in the code that check that update 
isn't executed twice simultaneously; this should be easily doable by the 
introduction of a static variable that is incremented when entering 
update and decrement when leaving update)
2. At the end of metrics computation & null painter, check whether 
there is a new event
3a. If yes, process the event, skip real painting
3b. If no, go on with real painting

Since real painting is suppressed if the user edits text very fast, this 
solution should be more efficient than the current one.

Michael


Re: [Patch] Table crash blues

2005-05-08 Thread Asger Ottar Alstrup
Michael Schmitt wrote:
So the "best" solution would be:
1. Run metrics computation & null painter as a single non-interruptable, 
non-reentrant step
(There should be some assertions in the code that check that update 
isn't executed twice simultaneously; this should be easily doable by the 
introduction of a static variable that is incremented when entering 
update and decrement when leaving update)
There already is such an assert. It is based on a bool, not a counter. 
There was a patch to change it to a counter, but I think that is wrong. 
The first time, we detect a reentrancy, we have the problem, and it 
should be fixed.

2. At the end of metrics computation & null painter, check whether there 
is a new event
3a. If yes, process the event, skip real painting
3b. If no, go on with real painting

Since real painting is suppressed if the user edits text very fast, this 
solution should be more efficient than the current one.
Yes, something like this should work better. This can be done in steps:
First, just leave the excessive painting as it is, but fix the 
re-entrancy problem. Then, as a second step, introduce the null-painter 
as an optimisation for the cases where two sequentive updates are coming 
right after each other, such as fast typing, which allows us to skip the 
first paint job.

The third step could be to build something like the update 
fingerprinting data-structure, as described earlier, which will help 
painting only what needs to be painted, and also help mitigate any 
excessive update calls there might be.

In parallel to this, all excessive update calls should be hunted down, 
and killed without mercy.

Regards,
Asger


Re: [Patch] Table crash blues

2005-05-08 Thread Michael Schmitt
Asger Ottar Alstrup wrote:
 (There should be some assertions in the code that check that update 
isn't executed twice simultaneously; this should be easily doable by 
the introduction of a static variable that is incremented when 
entering update and decrement when leaving update)
There already is such an assert. It is based on a bool, not a counter. 
There was a patch to change it to a counter, but I think that is wrong. 
You are right. A boolean is enough. Are you sure that the assert is 
already in the CVS repository?

First, just leave the excessive painting as it is, but fix the 
re-entrancy problem. Then, as a second step, introduce the 
null-painter ...
The third step could be to build something like the update 
fingerprinting data-structure ...
In parallel to this, all excessive update calls should be hunted down, 
and killed without mercy.
This sounds like an excellent approach.
Michael


Re: unneeded update() calls

2005-05-08 Thread Georg Baum
Am Sonntag, 8. Mai 2005 11:26 schrieb Asger Ottar Alstrup:
> Maybe you could add some comments about what the protocol for 
> update/noupdate calls is? Add it to the BufferView::update method, or 
> wherever the main update call is.

There is already a comment in LCursor::dispatch. In fact I got my 
knowledge from there :-) I added a more detailed one to 
InsetBase::doDispatch(), because this is the place where inset developers 
look.

> In general, I think the new code should be commented some more. Maybe 
> you do not understand exactly how it is supposed to work, but it is 
> still better to add a comment about how you understand it than not 
> adding something. Then, the people that understand it can post patches 
> to the comments.

I agree, and I added comments whenever I found it appropriate in the past.

I am going to commit the attached version of nobody objects.


Georg
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/ChangeLog lyx-1.4-cvs/src/insets/ChangeLog
--- lyx-1.4-clean/src/insets/ChangeLog	2005-05-08 11:59:27.0 +0200
+++ lyx-1.4-cvs/src/insets/ChangeLog	2005-05-08 12:41:25.0 +0200
@@ -1,3 +1,11 @@
+2005-05-08  Georg Baum  <[EMAIL PROTECTED]>
+
+	* insetbase.h (doDispatch): document a bit more
+	* insetcommand.C, insetfloat.C, insetgraphics.C, insetinclude.C,
+	insetnote.C, insetwrap.C, updatableinset.C (doDispatch): don't call
+	cur.bv().update(), because that leads to nested updates. Call
+	cur.noUpdate() instead where approriate.
+
 2005-05-07  Michael Schmitt  <[EMAIL PROTECTED]>
 
 	* insetbibtex.C: change screen label
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetbase.h lyx-1.4-cvs/src/insets/insetbase.h
--- lyx-1.4-clean/src/insets/insetbase.h	2005-04-23 10:15:04.0 +0200
+++ lyx-1.4-cvs/src/insets/insetbase.h	2005-05-08 12:27:43.0 +0200
@@ -402,8 +406,17 @@ public:
 protected:
 	InsetBase();
 	InsetBase(InsetBase const &);
-	/// the real dispatcher.
-	/// \sa getStatus
+	/** The real dispatcher.
+	 *  Gets normally called from LCursor::dispatch(). LCursor::dispatch()
+	 *  assumes the common case of 'LFUN handled, need update'.
+	 *  This has to be overriden by calling LCursor::undispatched() or
+	 *  LCursor::noUpdate() if appropriate.
+	 *  If you need to call the dispatch method of some inset directly
+	 *  you may have to explicitly request an update at that place. Don't
+	 *  do it in doDispatch(), since that causes nested updates when
+	 *  called from LCursor::dispatch(), and these can lead to crashes.
+	 *  \sa getStatus
+	 */
 	virtual void doDispatch(LCursor & cur, FuncRequest & cmd);
 private:
 	virtual std::auto_ptr doClone() const = 0;
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetcommand.C lyx-1.4-cvs/src/insets/insetcommand.C
--- lyx-1.4-clean/src/insets/insetcommand.C	2005-04-23 10:15:05.0 +0200
+++ lyx-1.4-cvs/src/insets/insetcommand.C	2005-05-08 10:47:07.0 +0200
@@ -109,12 +109,10 @@ void InsetCommand::doDispatch(LCursor & 
 	case LFUN_INSET_MODIFY: {
 		InsetCommandParams p;
 		InsetCommandMailer::string2params(mailer_name_, cmd.argument, p);
-		if (p.getCmdName().empty()) {
-			cur.undispatched();
-		} else {
+		if (p.getCmdName().empty())
+			cur.noUpdate();
+		else
 			setParams(p);
-			cur.bv().update();
-		}
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetfloat.C lyx-1.4-cvs/src/insets/insetfloat.C
--- lyx-1.4-clean/src/insets/insetfloat.C	2005-04-23 10:15:08.0 +0200
+++ lyx-1.4-cvs/src/insets/insetfloat.C	2005-05-08 10:44:43.0 +0200
@@ -160,7 +160,6 @@ void InsetFloat::doDispatch(LCursor & cu
 		params_.sideways  = params.sideways;
 		wide(params_.wide, cur.buffer().params());
 		sideways(params_.sideways, cur.buffer().params());
-		cur.bv().update();
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetgraphics.C lyx-1.4-cvs/src/insets/insetgraphics.C
--- lyx-1.4-clean/src/insets/insetgraphics.C	2005-04-23 10:15:08.0 +0200
+++ lyx-1.4-cvs/src/insets/insetgraphics.C	2005-05-08 10:43:21.0 +0200
@@ -197,10 +206,10 @@ void InsetGraphics::doDispatch(LCursor &
 		Buffer const & buffer = cur.buffer();
 		InsetGraphicsParams p;
 		InsetGraphicsMailer::string2params(cmd.argument, buffer, p);
-		if (!p.filename.empty()) {
+		if (!p.filename.empty())
 			setParams(p);
-			cur.bv().update();
-		}
+		else
+			cur.noUpdate();
 		break;
 	}
 
diff -p -r -U 3 -X excl.tmp lyx-1.4-clean/src/insets/insetinclude.C lyx-1.4-cvs/src/insets/insetinclude.C
--- lyx-1.4-clean/src/insets/insetinclude.C	2005-04-23 10:15:17.0 +0200
+++ lyx-1.4-cvs/src/insets/insetinclude.C	2005-05-08 10:43:57.0 +0200
@@ -128,10 +153,10 @@ void InsetInclude::doDispatch(LCursor & 
 	case LFUN_INSET_MODIFY: {
 		InsetCommandParams p;
 		InsetIncludeMailer::string2params(cmd.argument, p);
-		if (!p.getCmdName().empty()) {
+		if (!p.getCmdName().empty())
 			set(p, cur.buffer());
-			cur.bv().update();
-		}
+		else
+			cur.noUpdate();
 		b

Re: nested updates

2005-05-08 Thread Juergen Spitzmueller
Andre Poenitz wrote:
>  frontends/qt2/QDialogView.h:    qApp->processEvents();
> frontends/qt2/QDialogView.h:    qApp->processEvents();
> frontends/qt2/QDialogView.h:    qApp->processEvents();
> frontends/qt2/QDialogView.h:    qApp->processEvents();

No idea why/if they are needed, but I cannot reproduce the Asserts when I 
comment them out.

Jürgen


Re: [Patch] Table crash blues

2005-05-08 Thread Alfredo Braunstein
Andre Poenitz wrote:

> On Sat, May 07, 2005 at 09:21:20PM +0100, Angus Leeming wrote:
>> Andre Poenitz wrote:
>> > [Actually, there seems to be some bad Qt GUI interaction involved as
>> > [the
>> > problem shows only up when having certain dialogs open. Otherwise,
>> > plain full redraw seems to be fast enough...]
>> 
>> You reckon it's fast enough? 14x is *much* slower than 13x when using
>> over an ADSL line.
> 
> I haven't tried that, but local xform is certainly usably very well
> speed-wise.
> 
> We could save some network traffic by restricting actual drawing to some
> horizontal strip as we did in 1.3, but this would be new code, the old
> logic does not fit anymore.

And then, we 1.3.x only saved redraws when typing at the bottom of the
screen, not at the top, right? I don't think this is worth it, we need to
make speed uniform improvements, if any (IMHO).

Regards, Alfredo




Re: nested updates

2005-05-08 Thread Alfredo Braunstein
Andre Poenitz wrote:

> 
> 
> To our local Qt professionals:
> 
> Why do we need
> 
> [EMAIL PROTECTED]:/usr/src/lyx/lyx-devel/src > grep -R processEve *
> frontends/qt2/QDialogView.h:qApp->processEvents();
> frontends/qt2/QDialogView.h:qApp->processEvents();
> frontends/qt2/QDialogView.h:qApp->processEvents();
> frontends/qt2/QDialogView.h:qApp->processEvents();
> frontends/qt2/QMathDialog.C:qApp->processEvents();
> frontends/qt2/QMathDialog.C:qApp->processEvents();
> frontends/qt2/lyx_gui.C:qApp->processEvents();
> frontends/qt2/QLPopupMenu.C:qApp->processEvents();
> 
> One of these seems to be the cause of nested update() calls...

Well spotted... (and good question)

I suppose that this reentrance is what was causing problems in the last
scrollbar fix patch I've sent to the list a while ago.

Alfredo





Re: nested updates

2005-05-08 Thread Angus Leeming
Alfredo Braunstein wrote:

> Andre Poenitz wrote:
> 
>> 
>> 
>> To our local Qt professionals:
>> 
>> Why do we need
>> 
>> [EMAIL PROTECTED]:/usr/src/lyx/lyx-devel/src > grep -R processEve *
>> frontends/qt2/QDialogView.h:qApp->processEvents();
>> frontends/qt2/QDialogView.h:qApp->processEvents();
>> frontends/qt2/QDialogView.h:qApp->processEvents();
>> frontends/qt2/QDialogView.h:qApp->processEvents();
>> frontends/qt2/QMathDialog.C:qApp->processEvents();
>> frontends/qt2/QMathDialog.C:qApp->processEvents();
>> frontends/qt2/lyx_gui.C:qApp->processEvents();
>> frontends/qt2/QLPopupMenu.C:qApp->processEvents();
>> 
>> One of these seems to be the cause of nested update() calls...
> 
> Well spotted... (and good question)
> 
> I suppose that this reentrance is what was causing problems in the last
> scrollbar fix patch I've sent to the list a while ago.

I'd be most suspicious about these two:

lyx_gui.C:
void sync_events()
{
qApp->processEvents();
}

QLPopupMenu.C:
void QLPopupMenu::fire(int index)
{
qApp->processEvents();

The QDialogView ones are clearly ugly but are invoked only when building a
dialog or when updating its contents. Not stuff that happens during a
redraw of the contents of the main lyx screen.

sync_events appears to be called on each and every blink of the cursor:
void LyXScreen::showCursor(BufferView & bv)
{
// You are not expected to understand this. This forces Qt
// (the problem case) to deal with its event queue. This is
// necessary when holding down a key such as 'page down' or
// just typing: without this processing of the event queue,
// the cursor gets ahead of itself without a selection or
// workarea redraw having a chance to keep up. If you think
// you can remove this, try selecting text with the mouse
// in Qt, or holding Page Down on the User's Guide.
lyx_gui::sync_events();

The processEvents in QLPopupMenu::fire has this ChangeLog entry:

2004-08-13  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>

* QLPopupMenu.C (fire): make Qt process events before we
dispatch our function (toolbars still do not get repainted
correctly, though)

I'm not answering the 'why' these calls were felt to be needed, but I am
pointing out that they appear to 'solve' some specific problem.

Regards,
-- 
Angus



[PATCH 1.3] Postscript Interpreter: gswin32

2005-05-08 Thread Michael Schmitt
Hello,
Uwe pointed out that gswin32 is a Postscript interpreter used on the 
Windows platform. Though I don't have it on my machine, he's right.

I have created a small patch for 1.3, that extends the check of the 
configure script. Angus, Jean-Marc, could you please commit it?

(Please note that LyX 1.4 no longer checks for a Postscript interpreter. 
Therefore, there is no corresponding patch for 1.4.)

Thanks in advance,
Michael
Index: lib/ChangeLog
===
RCS file: /cvs/lyx/lyx-devel/lib/ChangeLog,v
retrieving revision 1.363.2.109
diff -u -p -r1.363.2.109 ChangeLog
--- lib/ChangeLog   2005/05/08 14:11:55 1.363.2.109
+++ lib/ChangeLog   2005/05/08 14:58:40
@@ -1,3 +1,7 @@
+2005-05-08  Michael Schmitt  <[EMAIL PROTECTED]>
+
+   * lib/configure.m4: support gswin32 as Postscript interpreter
+
 2005-05-08  Angus Leeming  <[EMAIL PROTECTED]>
 
* scripts/lyxpreview2ppm.py: do not quote the name of the
Index: lib/configure.m4
===
RCS file: /cvs/lyx/lyx-devel/lib/configure.m4,v
retrieving revision 1.60.2.18
diff -u -p -r1.60.2.18 configure.m4
--- lib/configure.m42005/04/22 16:39:04 1.60.2.18
+++ lib/configure.m42005/05/08 14:58:41
@@ -265,7 +265,7 @@ SEARCH_PROG([for Image converter],image_
 test $image_command = "convert" && image_command="convert \$\$i \$\$o"
 
 # Search for a Postscript interpreter
-LYXRC_PROG([for a Postscript interpreter], \ps_command, gs)
+LYXRC_PROG([for a Postscript interpreter],\ps_command,gswin32 gs)
 
 # Search something to preview postscript
 SEARCH_PROG([for a Postscript previewer],GHOSTVIEW,gsview32 gv ghostview)


Re: [PATCH 1.3] Postscript Interpreter: gswin32

2005-05-08 Thread Angus Leeming
Michael Schmitt wrote:

> Hello,
> 
> Uwe pointed out that gswin32 is a Postscript interpreter used on the
> Windows platform. Though I don't have it on my machine, he's right.
> 
> I have created a small patch for 1.3, that extends the check of the
> configure script. Angus, Jean-Marc, could you please commit it?

Shouldn't we be using gswin32c, the command-line version that doesn't pop
up a console window when it is invoked?

$ ls /mnt/windowsC/Program\ Files/Ghostscript\ 8.33/gs8.33/bin
gsdll32.dll  gsdll32.lib  gswin32c.exe  gswin32.exe

If I'd know about gswin32c.exe I woulnd't have spent two months writing
lyxpreview2pnm.py so that it prevents that bloody konsole from popping up
when it's not wanted :(

Grr!

-- 
Angus



Preamble

2005-05-08 Thread Michael Schmitt
Hello,
could anybody please enlighten me? In lib/ui/stdmenus.ui, the following 
entry is given for "document"

 Item "LaTeX Preamble...|P" "dialog-show preamble"
But when I start LyX, there is no menu entry called "LaTeX Preamble" in 
the LyX Document menu! Even more surprising, when I enter "dialog-show 
preamble" in the command buffer, the "Document Settings" dialog opens. 
What is going on here?

Michael (puzzled)


Re: Preamble

2005-05-08 Thread Angus Leeming
Michael Schmitt wrote:

> Hello,
> 
> could anybody please enlighten me? In lib/ui/stdmenus.ui, the following
> entry is given for "document"
> 
>   Item "LaTeX Preamble...|P" "dialog-show preamble"
> 
> But when I start LyX, there is no menu entry called "LaTeX Preamble" in
> the LyX Document menu! Even more surprising, when I enter "dialog-show
> preamble" in the command buffer, the "Document Settings" dialog opens.
> What is going on here?
> 
> Michael (puzzled)

There is (an entry called "LaTeX Preamble") in the XForms frontend. In the
Qt frontend the dialog has been merged into the Document dialog.
Unfortunately, our attempts to do this to XForms foundered because the
result 'felt' bad. One more reason to ditch XForms.

-- 
Angus



Re: [PATCH 1.3] Postscript Interpreter: gswin32

2005-05-08 Thread Angus Leeming
Michael Schmitt wrote:
>> Shouldn't we be using gswin32c, the command-line version that doesn't
>> pop
>>
>>up a console window when it is invoked?
>>
>>$ ls /mnt/windowsC/Program\ Files/Ghostscript\ 8.33/gs8.33/bin
>>gsdll32.dll  gsdll32.lib  gswin32c.exe  gswin32.exe
>>
>>If I'd know about gswin32c.exe I woulnd't have spent two months writing
>>lyxpreview2pnm.py so that it prevents that bloody konsole from popping up
>>when it's not wanted :(
>>  
>>
> Is this a question or a statement?

Both. You use Windows, I try not to. I learn vicariously through the
experience of others. Can you find out from Uwe whether gswin32c exists on
his box and whether it 'feels' nicer to use it.

> Feel free to modify the patch. 

Sorry. It's Sunday and I'm feeling lazy.

-- 
Angus



Re: [PATCH 1.3] Postscript Interpreter: gswin32

2005-05-08 Thread Michael Schmitt
Angus Leeming wrote:
Shouldn't we be using gswin32c, the command-line version that doesn't pop
up a console window when it is invoked?
$ ls /mnt/windowsC/Program\ Files/Ghostscript\ 8.33/gs8.33/bin
gsdll32.dll  gsdll32.lib  gswin32c.exe  gswin32.exe
If I'd know about gswin32c.exe I woulnd't have spent two months writing
lyxpreview2pnm.py so that it prevents that bloody konsole from popping up
when it's not wanted :(
 

Is this a question or a statement? Feel free to modify the patch.
Michael


Re: nested updates

2005-05-08 Thread John Levon
On Sun, May 08, 2005 at 03:50:56PM +0100, Angus Leeming wrote:

> sync_events appears to be called on each and every blink of the cursor:
> void LyXScreen::showCursor(BufferView & bv)
> {
> // You are not expected to understand this. This forces Qt
> // (the problem case) to deal with its event queue. This is
> // necessary when holding down a key such as 'page down' or
> // just typing: without this processing of the event queue,
> // the cursor gets ahead of itself without a selection or
> // workarea redraw having a chance to keep up. If you think
> // you can remove this, try selecting text with the mouse
> // in Qt, or holding Page Down on the User's Guide.
> lyx_gui::sync_events();

People have tried to take this out before, hence the comment. I can
almost guarantee it will break if you try to remove it. Sorry, I don't
know of a good solution either.

But I'm a bit confused as to why this is an issue: when I rewrote the
cursor handling, I'm pretty sure I made it so that showCursor is only
/ever/ called right at the end of an update (that is, after processing
an LFUN). So I don't see why this is nesting, unless somebody has
changed this behaviour.

The dialog ones are necessary because we want the dialogs to rebuild
their sizes etc. when we can't see the individual updates. If we had a
way to just update the dialog's events...

I have no idea why QLPopupMenu::fire() has one, but again, this should
not be a problem.

regards
john


[PATCH] reference-goto

2005-05-08 Thread Michael Schmitt
Sorry,
I forgot to fix a few more occurrences of "reference-goto". Please apply.
Thanks, Michael
Index: ChangeLog
===
RCS file: /cvs/lyx/lyx-devel/lib/ChangeLog,v
retrieving revision 1.696
diff -u -p -r1.696 ChangeLog
--- ChangeLog	2005/05/08 14:11:39	1.696
+++ ChangeLog	2005/05/08 16:58:17
@@ -1,3 +1,8 @@
+2005-05-08  Michael Schmitt  <[EMAIL PROTECTED]>
+
+	* bind/*.bind
+	* doc/*Customization: change "reference-goto" to "label-goto"
+
 2005-05-08  Angus Leeming  <[EMAIL PROTECTED]>
 
 	* scripts/lyxpreview2bitmap.py:
Index: bind/aqua.bind
===
RCS file: /cvs/lyx/lyx-devel/lib/bind/aqua.bind,v
retrieving revision 1.7
diff -u -p -r1.7 aqua.bind
--- bind/aqua.bind	2005/01/15 18:36:02	1.7
+++ bind/aqua.bind	2005/05/08 16:58:17
@@ -131,7 +131,7 @@
 
 \bind "M-~S-n e"		"error-next"
 \bind "M-~S-n n"		"note-next"
-\bind "M-~S-n r"		"reference-goto"
+\bind "M-~S-n r"		"label-goto"
 \bind "M-~S-n b s"		"bookmark-save 1"
 \bind "M-~S-n b 1"		"bookmark-goto 1"
 \bind "M-~S-n b 2"		"bookmark-goto 2"
Index: bind/cua.bind
===
RCS file: /cvs/lyx/lyx-devel/lib/bind/cua.bind,v
retrieving revision 1.32
diff -u -p -r1.32 cua.bind
--- bind/cua.bind	2005/01/15 18:36:02	1.32
+++ bind/cua.bind	2005/05/08 16:58:18
@@ -107,7 +107,7 @@
 \bind "C-Home"			"buffer-begin"
 \bind "C-End"			"buffer-end"
 
-\bind "C-~S-greater"		"reference-goto"
+\bind "C-~S-greater"		"label-goto"
 \bind "C-~S-less" 		"bookmark-goto 0"
 
 
Index: bind/emacs.bind
===
RCS file: /cvs/lyx/lyx-devel/lib/bind/emacs.bind,v
retrieving revision 1.29
diff -u -p -r1.29 emacs.bind
--- bind/emacs.bind	2005/01/15 18:36:02	1.29
+++ bind/emacs.bind	2005/05/08 16:58:18
@@ -148,7 +148,7 @@
 \bind "M-~S-less"		"buffer-begin"
 \bind "M-~S-greater"		"buffer-end"
 
-\bind "C-~S-greater"		"reference-goto"
+\bind "C-~S-greater"		"label-goto"
 \bind "C-~S-less" 		"bookmark-goto 0"
 \bind "C-~S-1"			"bookmark-goto 1"
 \bind "C-~S-2"			"bookmark-goto 2"
Index: bind/mac.bind
===
RCS file: /cvs/lyx/lyx-devel/lib/bind/mac.bind,v
retrieving revision 1.7
diff -u -p -r1.7 mac.bind
--- bind/mac.bind	2005/01/15 18:36:02	1.7
+++ bind/mac.bind	2005/05/08 16:58:18
@@ -96,7 +96,7 @@
 \bind "C-Right" "line-end"
 \bind "C-Left"  "line-begin"
 
-\bind "C-~S-greater"		"reference-goto"
+\bind "C-~S-greater"		"label-goto"
 \bind "C-~S-less" 		"bookmark-goto 0"
 
 
Index: bind/xemacs.bind
===
RCS file: /cvs/lyx/lyx-devel/lib/bind/xemacs.bind,v
retrieving revision 1.31
diff -u -p -r1.31 xemacs.bind
--- bind/xemacs.bind	2005/01/15 18:36:02	1.31
+++ bind/xemacs.bind	2005/05/08 16:58:19
@@ -163,7 +163,7 @@
 # A bit like autoindent in c-mode
 \bind "Tab" "depth-increment"
 
-\bind "C-~S-greater"		"reference-goto"
+\bind "C-~S-greater"		"label-goto"
 \bind "C-~S-less" 		"bookmark-goto 0"
 \bind "C-~S-1"			"bookmark-goto 1"
 \bind "C-~S-2"			"bookmark-goto 2"
Index: doc/Customization.lyx
===
RCS file: /cvs/lyx/lyx-devel/lib/doc/Customization.lyx,v
retrieving revision 1.7
diff -u -p -r1.7 Customization.lyx
--- doc/Customization.lyx	2005/02/04 12:44:22	1.7
+++ doc/Customization.lyx	2005/05/08 16:58:30
@@ -12154,7 +12154,7 @@ C-S-greater
 \family default 
  
 \family typewriter 
-reference-goto
+label-goto
 \layout List
 \labelwidthstring 00.00.
 
@@ -12697,7 +12697,7 @@ C-S-greater
 \family default 
  
 \family typewriter 
-reference-goto
+label-goto
 \layout List
 \labelwidthstring 00.00.
 
Index: doc/de_Customization.lyx
===
RCS file: /cvs/lyx/lyx-devel/lib/doc/de_Customization.lyx,v
retrieving revision 1.1
diff -u -p -r1.1 de_Customization.lyx
--- doc/de_Customization.lyx	2004/06/01 19:50:10	1.1
+++ doc/de_Customization.lyx	2005/05/08 16:58:45
@@ -15525,7 +15525,7 @@ C-S-greater
 \family default 
  
 \family typewriter 
-reference-goto
+label-goto
 \layout List
 \labelwidthstring 00.00.
 
@@ -16068,7 +16068,7 @@ C-S-greater
 \family default 
  
 \family typewriter 
-reference-goto
+label-goto
 \layout List
 \labelwidthstring 00.00.
 
Index: doc/eu_Customization.lyx
===
RCS file: /cvs/lyx/lyx-devel/lib/doc/eu_Customization.lyx,v
retrieving revision 1.1
diff -u -p -r1.1 eu_Customization.lyx
--- doc/eu_Customization.lyx	2004/06/01 19:50:11	1.1
+++ doc/eu_Customization.lyx	2005/05/08 16:58:55
@@ -10174,7 +10174,7 @@ C-S-greater
 \family default 
  
 \family typewriter 
-reference-goto
+label-goto
 \layout Labeling
 \labelwidthstring 00.00.
 
@@ -10719,7 +10719,7 @@ C-S-greater
 \family de

Re: nested updates

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 01:35:10PM +0200, Juergen Spitzmueller wrote:
> Andre Poenitz wrote:
> > frontends/qt2/QDialogView.h: qApp->processEvents();
> > frontends/qt2/QDialogView.h: qApp->processEvents();
> > frontends/qt2/QDialogView.h: qApp->processEvents();
> > frontends/qt2/QDialogView.h: qApp->processEvents();
> 
> No idea why/if they are needed, but I cannot reproduce the Asserts when I 
> comment them out.

Surprise. So this is indeed the cause for the nested updates.

What does the person named `cvs blame | grep processEvents | cut -c 15-23`
say in his defense?

Andre'


Re: [Patch] Table crash blues

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 10:53:08AM +0200, Michael Schmitt wrote:
> Andre Poenitz wrote:
> 
> >>I see.  The coord cache must be updated, but I hope the actual drawing
> >>can be skipped ??? when lyx knows that it is behind.  That improves
> >>performance in many cases, such as an overloaded machine or X over a
> >>slow network.
> >>   
> >>
> >The coord cache is filled in the drawing phase (the metrics phase fills
> >the size part of the coord cache only). We _do_ have a 'null painter'
> >which only fills the cache, but if we did metrics + null painter
> >painting + real painting in every case, drawing might get slow. Just a
> >suspicion, though.
> > 
> >
> Hmmm, I would have expected that the only expensive operations is the 
> real painting (provided that the null painter does not invoke any X/Qt 
> methods).

I've never timed this, so this may be true. There is some font handling 
necessary and stuff like this shows up in the profile sometimes.

> Is it possible to combine metrics & null painter?

No. The split in metrics + drawing phase is there because the drawing
phase needs position in its parent and size of all childrenb, so this is
not possible in a single phase.
 
> Without knowing the details, I think the only clean solution is to avoid 
> recursive/reentrant updates completely.

It would certainly be a clean and robust soution. xforms seems to work
without recursive updates, so I wonder why the Qt frontend needs to call
processEvents() at all. 

> I always prefer stability over performance.

I don't eeven think this is a performance problem here, just some ugly
hack we put there in becuase it seemed to work

Andre'


Re: unneeded update() calls

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 10:57:04AM +0200, Georg Baum wrote:
> I did also call noUpdate() instead of undispatched() in insetcommand.C. Is 
> that correct?

'undispatched' means: I, the doDispatch() method of InsetFoo, hereby
declare that I am not able to handle that request and trust my parent
will do the Rigth Thing (even if my getStatus partner said that I can do
it). It is sort of a kludge that should be used only rarely...

noUpdate() means: I handled that request and I can reassure you that the
screen does not need to be re-drawn and all entries in the coord cache
stay valid (and there are no other thing to put in the coord cache).
This is a fairly rare event as well and only some optimization. Not
using noUpdate() should never be wrong.

Andre' 


Re: [Patch] Table crash blues

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 01:05:00PM +0200, Michael Schmitt wrote:
> Asger Ottar Alstrup wrote:
> 
> >> (There should be some assertions in the code that check that update 
> >>isn't executed twice simultaneously; this should be easily doable by 
> >>the introduction of a static variable that is incremented when 
> >>entering update and decrement when leaving update)
> >
> >There already is such an assert. It is based on a bool, not a counter. 
> >There was a patch to change it to a counter, but I think that is wrong. 
> 
> You are right. A boolean is enough. Are you sure that the assert is 
> already in the CVS repository?

It isn't, at least not in BufferView_pimpl::update(). There are some
weaker asserts further down the pipeline.

Andre'


Re: [Patch] Table crash blues

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 12:05:50PM +0200, Michael Schmitt wrote:
> Asger Ottar Alstrup wrote:
> 
> >A better fix is to go to the root of the cause, and in this case, as 
> >mentioned in another post, I believe the right fix is to either omit 
> >or postpone the qApps->processEvent calls during update.
> >
> >Of course, excessive update calls from other places, as found by 
> >George, should also be nailed. (Notice, that the optimisation as 
> >sketched out would reduce the cost of superfluous update calls to a 
> >metrics and null-paint job only - the outcome would be identical to 
> >before, and no painting on screen would be necessary).
> 
> So the "best" solution would be:
> 
> 1. Run metrics computation & null painter as a single 

This is conceptually impossible. If using the nullpainter turns out to
be cheap, we could have a three-phase update (metrics + nullpainter +
painter) and safely skip the third phase when needed (i.e. the next
update is already pending).

> non-interruptable, non-reentrant step
> (There should be some assertions in the code that check that update 
> isn't executed twice simultaneously; this should be easily doable by the 
> introduction of a static variable that is incremented when entering 
> update and decrement when leaving update)
> 2. At the end of metrics computation & null painter, check whether 
> there is a new event
> 3a. If yes, process the event, skip real painting
> 3b. If no, go on with real painting

The rest is ok. In any case this will be quite some reorganzition of all
current inset drawing code and I think we should try to remove the
processEvent calls first.
 
> Since real painting is suppressed if the user edits text very fast, this 
> solution should be more efficient than the current one.

I some situations yes. In some (when the user types slowly or the
machine is fast enouhg), not.

Andre'


Re: nested updates

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 03:50:56PM +0100, Angus Leeming wrote:
> sync_events appears to be called on each and every blink of the cursor:
> void LyXScreen::showCursor(BufferView & bv)
> {
> // You are not expected to understand this. This forces Qt
> // (the problem case) to deal with its event queue. This is
> // necessary when holding down a key such as 'page down' or
> // just typing: without this processing of the event queue,
> // the cursor gets ahead of itself without a selection or
> // workarea redraw having a chance to keep up. If you think
> // you can remove this, try selecting text with the mouse
> // in Qt, or holding Page Down on the User's Guide.
> lyx_gui::sync_events();
> [...]
> I'm not answering the 'why' these calls were felt to be needed, but I am
> pointing out that they appear to 'solve' some specific problem.

Now a verification of these 'problems' would be in order, wouldn't it?

Andre'


Re: [Patch] Table crash blues

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 04:21:44PM +0200, Alfredo Braunstein wrote:
> > We could save some network traffic by restricting actual drawing to some
> > horizontal strip as we did in 1.3, but this would be new code, the old
> > logic does not fit anymore.
> 
> And then, we 1.3.x only saved redraws when typing at the bottom of the
> screen, not at the top, right?

Something like that, yes. 

> I don't think this is worth it, we need to
> make speed uniform improvements, if any (IMHO).

Indeed. And I'll only start to consider speed hacks if something turns
out to be unusable slow when using the simple approach... 

Andre'


Re: [Patch] Table crash blues

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 12:16:27PM +0200, Asger Ottar Alstrup wrote:
> Yes, something like this should work better. This can be done in steps:
> 
> First, just leave the excessive painting as it is, but fix the 
> re-entrancy problem. Then, as a second step, introduce the null-painter 
> as an optimisation for the cases where two sequentive updates are coming 
> right after each other, such as fast typing, which allows us to skip the 
> first paint job.
> 
> The third step could be to build something like the update 
> fingerprinting data-structure, as described earlier, which will help 
> painting only what needs to be painted, and also help mitigate any 
> excessive update calls there might be.
> 
> In parallel to this, all excessive update calls should be hunted down, 
> and killed without mercy.

Ok, so everybody knows the plan now...

Andre'


Re: nested updates

2005-05-08 Thread Martin Vermeer
On Sun, May 08, 2005 at 07:56:47PM +0200, Andre Poenitz wrote:
> On Sun, May 08, 2005 at 03:50:56PM +0100, Angus Leeming wrote:
> > sync_events appears to be called on each and every blink of the cursor:
> > void LyXScreen::showCursor(BufferView & bv)
> > {
> > // You are not expected to understand this. This forces Qt
> > // (the problem case) to deal with its event queue. This is
> > // necessary when holding down a key such as 'page down' or
> > // just typing: without this processing of the event queue,
> > // the cursor gets ahead of itself without a selection or
> > // workarea redraw having a chance to keep up. If you think
> > // you can remove this, try selecting text with the mouse
> > // in Qt, or holding Page Down on the User's Guide.
> > lyx_gui::sync_events();
> > [...]
> > I'm not answering the 'why' these calls were felt to be needed, but I am
> > pointing out that they appear to 'solve' some specific problem.
> 
> Now a verification of these 'problems' would be in order, wouldn't it?
> 
> Andre'

Let us first make sure which of these processEvents() are actually
causing our 'table blues' problem(s). Surely not all of them.

- Martin



pgpmTIQ409l52.pgp
Description: PGP signature


Re: nested updates

2005-05-08 Thread Martin Vermeer
On Sun, May 08, 2005 at 05:50:08PM +0100, John Levon wrote:
> On Sun, May 08, 2005 at 03:50:56PM +0100, Angus Leeming wrote:
> 
> > sync_events appears to be called on each and every blink of the cursor:
> > void LyXScreen::showCursor(BufferView & bv)
> > {
> > // You are not expected to understand this. This forces Qt
> > // (the problem case) to deal with its event queue. This is
> > // necessary when holding down a key such as 'page down' or
> > // just typing: without this processing of the event queue,
> > // the cursor gets ahead of itself without a selection or
> > // workarea redraw having a chance to keep up. If you think
> > // you can remove this, try selecting text with the mouse
> > // in Qt, or holding Page Down on the User's Guide.
> > lyx_gui::sync_events();
> 
> People have tried to take this out before, hence the comment. I can
> almost guarantee it will break if you try to remove it. Sorry, I don't
> know of a good solution either.
> 
> But I'm a bit confused as to why this is an issue: when I rewrote the
> cursor handling, I'm pretty sure I made it so that showCursor is only
> /ever/ called right at the end of an update (that is, after processing
> an LFUN). So I don't see why this is nesting, unless somebody has
> changed this behaviour.

You mean the hideCursor/showCursor mechanism in redraw()? 

But... isn't this cursor drawing and hiding an asynchronous process
taking place every 400 msec? What happens if a drawing activity takes
longer than 400 (800?) msec and the cursor comes back all of itself in
the middle of it?

Only Qt has a working sync_events right now...

- Martin



pgpFWn18NaV7c.pgp
Description: PGP signature


Re: nested updates

2005-05-08 Thread John Levon
On Sun, May 08, 2005 at 10:37:33PM +0300, Martin Vermeer wrote:

> But... isn't this cursor drawing and hiding an asynchronous process
> taking place every 400 msec? What happens if a drawing activity takes
> longer than 400 (800?) msec and the cursor comes back all of itself in
> the middle of it?

Right, looks like a problem. We should just set a variable and then only
update the cursor at the end.

john


Re: nested updates

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 05:50:08PM +0100, John Levon wrote:
> But I'm a bit confused as to why this is an issue: when I rewrote the
> cursor handling, I'm pretty sure I made it so that showCursor is only
> /ever/ called right at the end of an update (that is, after processing
> an LFUN). So I don't see why this is nesting, unless somebody has
> changed this behaviour.

Somebody seemingly has:

void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key,
 key_modifier::state state)
{
owner_->getLyXFunc().processKeySym(key, state);

/* This is perhaps a bit of a hack. When we move
 * around, or type, it's nice to be able to see
 * the cursor immediately after the keypress. So
 * we reset the toggle timeout and force the visibility
 * of the cursor. Note we cannot do this inside
 * dispatch() itself, because that's called recursively.
 */
if (available()) {
cursor_timeout.restart();
screen().showCursor(*bv_);  // !!!
}
}

Note the line marked with !!!.  This workAreaKeyPress shows btw up in
the backtrace of a nested update call.

> The dialog ones are necessary because we want the dialogs to rebuild
> their sizes etc. when we can't see the individual updates. If we had a
> way to just update the dialog's events...

I don't care how the dialog manage to rebuild there sizes if the core
crashes. And there should be some solution as xforms can do it without.

What's wrong with a signal emitted at the end of update() to which all
interested dialogs can connect?

Andre'


Re: nested updates

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 05:50:08PM +0100, John Levon wrote:
> The dialog ones are necessary because we want the dialogs to rebuild
> their sizes etc. when we can't see the individual updates. If we had a
> way to just update the dialog's events...

I do not really understand what you mean here. Maybe you could add a
sentence or two?

Andre'

PS: I have the impression that processEvents is rarely (if ever) needed
outside Qt library code. It introduces concurrency problems even in
single threaded applications that are not designed for this kind of
scenario. 


Re: nested updates

2005-05-08 Thread Andre Poenitz
On Sun, May 08, 2005 at 08:41:26PM +0100, John Levon wrote:
> On Sun, May 08, 2005 at 10:37:33PM +0300, Martin Vermeer wrote:
> 
> > But... isn't this cursor drawing and hiding an asynchronous process
> > taking place every 400 msec? What happens if a drawing activity takes
> > longer than 400 (800?) msec and the cursor comes back all of itself in
> > the middle of it?
> 
> Right, looks like a problem. We should just set a variable and then only
> update the cursor at the end.

What about removing cursor and cursor blinking timer at the begin of
update and start a new timer with a shown cursorat the end of update?

Wouldn't this also address what that BufferView::Pimpl::workAreaKeyPress
'hack' is supposed to solve?

Andre'


nested updates

2005-05-08 Thread John Levon

> Note the line marked with !!!.  This workAreaKeyPress shows btw up in
> the backtrace of a nested update call.

Why are we calling workAreaKeyPress() during an update?

> I don't care how the dialog manage to rebuild there sizes if the core
> crashes.

The core didn't used to crash in 1.3. You can't blame other code for
changes you've decided are necessary...

> And there should be some solution as xforms can do it without.

xforms is completely different from Qt.

> What's wrong with a signal emitted at the end of update() to which all
> interested dialogs can connect?

Might work OK. Or just delay the frontend dialog's update() until the
core has finished updating.

regards,
john


Re: nested updates

2005-05-08 Thread John Levon
On Sun, May 08, 2005 at 10:28:59PM +0200, Andre Poenitz wrote:

> What about removing cursor and cursor blinking timer at the begin of
> update and start a new timer with a shown cursorat the end of update?

Sounds very sensible to me.

regards
john


Re: nested updates

2005-05-08 Thread Martin Vermeer
On Sun, May 08, 2005 at 09:33:55PM +0100, John Levon wrote:
> On Sun, May 08, 2005 at 10:28:59PM +0200, Andre Poenitz wrote:
> 
> > What about removing cursor and cursor blinking timer at the begin of
> > update and start a new timer with a shown cursorat the end of update?
> 
> Sounds very sensible to me.

Or... replace the current hideCursor/showCursor pair by a boolean
LyXScreen::allow_sync_ that is set to false before, to true after redraw
and tested inside showCursor making the sync_events() call conditional.

- Martin



pgp01pFbOcSLv.pgp
Description: PGP signature


Re: nested updates

2005-05-08 Thread Martin Vermeer
On Sun, May 08, 2005 at 08:20:55PM +0200, Andre Poenitz wrote:
> On Sun, May 08, 2005 at 05:50:08PM +0100, John Levon wrote:

...
 
> void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key,
>key_modifier::state state)
> {
>   owner_->getLyXFunc().processKeySym(key, state);
> 
>   /* This is perhaps a bit of a hack. When we move
>* around, or type, it's nice to be able to see
>* the cursor immediately after the keypress. So
>* we reset the toggle timeout and force the visibility
>* of the cursor. Note we cannot do this inside
>* dispatch() itself, because that's called recursively.
>*/
>   if (available()) {
>   cursor_timeout.restart();
>   screen().showCursor(*bv_);  // !!!
>   }
> }
> 
> Note the line marked with !!!.  This workAreaKeyPress shows btw up in
> the backtrace of a nested update call.

Hmmm, wouldn't it be enough to just send the cursor_timeout.timeout 
signal here? 

- Martin



pgpXfbKmf92bj.pgp
Description: PGP signature


Re: [PATCH 1.3] Postscript Interpreter: gswin32

2005-05-08 Thread Uwe Stöhr
Angus Leeming wrote:
Can you find out from Uwe whether gswin32c exists on
his box and whether it 'feels' nicer to use it.
gswin32c.exe is part of all ghostscript win installations. It changes to 
a gs prompt in the win console. In contrast gswin32.exe opens a new 
window with a gs console.
Both are ok, "feeling nicer" is relative so please decide to use what 
you prefer.

regards Uwe


Re: [PATCH 1.3] Postscript Interpreter: gswin32

2005-05-08 Thread Michael Schmitt
Angus Leeming wrote:
Both. You use Windows, I try not to. I learn vicariously through the
experience of others. Can you find out from Uwe whether gswin32c exists on
his box and whether it 'feels' nicer to use it.
 

Since Uwe has no objections, let's use gswin32c.
Angus, Jean-Marc, please apply the new patch.
Michael
Index: ChangeLog
===
RCS file: /cvs/lyx/lyx-devel/lib/ChangeLog,v
retrieving revision 1.363.2.109
diff -u -p -r1.363.2.109 ChangeLog
--- ChangeLog   2005/05/08 14:11:55 1.363.2.109
+++ ChangeLog   2005/05/09 05:39:31
@@ -1,3 +1,7 @@
+2005-05-08  Michael Schmitt  <[EMAIL PROTECTED]>
+
+   * lib/configure.m4: support gswin32c as Postscript interpreter
+
 2005-05-08  Angus Leeming  <[EMAIL PROTECTED]>
 
* scripts/lyxpreview2ppm.py: do not quote the name of the
Index: configure.m4
===
RCS file: /cvs/lyx/lyx-devel/lib/configure.m4,v
retrieving revision 1.60.2.18
diff -u -p -r1.60.2.18 configure.m4
--- configure.m42005/04/22 16:39:04 1.60.2.18
+++ configure.m42005/05/09 05:39:39
@@ -265,7 +265,7 @@ SEARCH_PROG([for Image converter],image_
 test $image_command = "convert" && image_command="convert \$\$i \$\$o"
 
 # Search for a Postscript interpreter
-LYXRC_PROG([for a Postscript interpreter], \ps_command, gs)
+LYXRC_PROG([for a Postscript interpreter],\ps_command,gswin32c gs)
 
 # Search something to preview postscript
 SEARCH_PROG([for a Postscript previewer],GHOSTVIEW,gsview32 gv ghostview)


[PATCH] shortcut

2005-05-08 Thread Michael Schmitt
Hello,
this patch fixes the shortcuts for "Cross-reference".
Please apply to LyX 1.4.
Thanks, Michael
Index: ChangeLog
===
RCS file: /cvs/lyx/lyx-devel/lib/ChangeLog,v
retrieving revision 1.696
diff -u -p -r1.696 ChangeLog
--- ChangeLog	2005/05/08 14:11:39	1.696
+++ ChangeLog	2005/05/09 05:49:45
@@ -1,3 +1,8 @@
+2005-05-09  Michael Schmitt  <[EMAIL PROTECTED]>
+
+	* ui/classic.ui:
+	* ui/stdmenus.ui: fix shortcut for Cross-reference
+
 2005-05-08  Angus Leeming  <[EMAIL PROTECTED]>
 
 	* scripts/lyxpreview2bitmap.py:
Index: ui/classic.ui
===
RCS file: /cvs/lyx/lyx-devel/lib/ui/classic.ui,v
retrieving revision 1.17
diff -u -p -r1.17 classic.ui
--- ui/classic.ui	2005/05/08 10:02:35	1.17
+++ ui/classic.ui	2005/05/09 05:50:45
@@ -211,7 +211,7 @@ Menuset
 		Separator
 		Submenu "Special Character|S" "insert_special"
 		Item "Citation...|C" "dialog-show-new-inset citation"
-		Item "Cross-reference...|R" "dialog-show-new-inset ref"
+		Item "Cross-reference...|r" "dialog-show-new-inset ref"
 		Item "Label...|L" "label-insert"
 		Item "Footnote|F" "footnote-insert"
 		Item "Marginal Note|M" "marginalnote-insert"
Index: ui/stdmenus.ui
===
RCS file: /cvs/lyx/lyx-devel/lib/ui/stdmenus.ui,v
retrieving revision 1.46
diff -u -p -r1.46 stdmenus.ui
--- ui/stdmenus.ui	2005/05/08 10:02:35	1.46
+++ ui/stdmenus.ui	2005/05/09 05:50:45
@@ -237,7 +237,7 @@ Menuset
 		Item "Box" "box-insert Frameless"
 		Separator
 		Item "Citation...|C" "dialog-show-new-inset citation"
-		Item "Cross-reference...|R" "dialog-show-new-inset ref"
+		Item "Cross-reference...|r" "dialog-show-new-inset ref"
 		Item "Label...|L" "label-insert"
 		Item "Index Entry|d" "index-insert"
 # I'm going to kill this dumb dialog, but for now ...


Re: nested updates

2005-05-08 Thread Martin Vermeer
On Sun, May 08, 2005 at 08:41:26PM +0100, John Levon wrote:
> On Sun, May 08, 2005 at 10:37:33PM +0300, Martin Vermeer wrote:
> 
> > But... isn't this cursor drawing and hiding an asynchronous process
> > taking place every 400 msec? What happens if a drawing activity takes
> > longer than 400 (800?) msec and the cursor comes back all of itself in
> > the middle of it?
> 
> Right, looks like a problem. We should just set a variable and then only
> update the cursor at the end.
> 
> john

I tried the attached. The net effect is, that the table crashes we have
seen disappear, but instead we get a new crash. It is the assert in
startUpdating(), signaling an overrun of the screen redraw by the
keyboard input. The relevant part of the stack is (sorry for no symbols):

#4  0x080a39c2 in boost::assertion_failed (expr=0x83a7458 "!updating", 
function=0x83a73a0 "void CoordCache::startUpdating()", 
file=0x83a744b "coordcache.C", line=43) at boost.C:56
#5  0x080d41ee in CoordCache::startUpdating () at stl_deque.h:126
#6  0x08069f63 in BufferView::Pimpl::update () at basic_string.h:910
#7  0x080634ba in BufferView::update () at ButtonPolicies.h:70
#8  0x08116c8d in LyXFunc::dispatch () at basic_string.h:358
#9  0x0810f77d in LyXFunc::processKeySym () at basic_string.h:358
#10 0x080698d5 in BufferView::Pimpl::workAreaKeyPress () at basic_string.h:910

Apparently we ought to be able to queue incoming keystrokes / dispatches for 
the duration of redraw (using, e.g., my proposed isUpdating() method in
coordcache). I remember Asger suggesting this much yesterday.

Suggestions how and where to do this?  LyXFunc?

- Martin

PS NOTE the problem is _not_ the showCursor call later on in
workAreaKeyPress. It's the processKeySym call followed by the dispatch chain.

Index: screen.C
===
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/screen.C,v
retrieving revision 1.101
diff -u -p -r1.101 screen.C
--- screen.C11 Feb 2005 18:07:06 -  1.101
+++ screen.C9 May 2005 06:21:34 -
@@ -122,7 +122,7 @@ SplashScreen::SplashScreen()
 
 
 LyXScreen::LyXScreen()
-   : greyed_out_(true), cursor_visible_(false)
+   : greyed_out_(true), cursor_visible_(false), sync_allowed_(true)
 {
// Start loading the pixmap as soon as possible
if (lyxrc.show_banner) {
@@ -155,7 +155,8 @@ void LyXScreen::showCursor(BufferView & 
// workarea redraw having a chance to keep up. If you think
// you can remove this, try selecting text with the mouse
// in Qt, or holding Page Down on the User's Guide.
-   lyx_gui::sync_events();
+   if (sync_allowed_)
+   lyx_gui::sync_events();
 
if (cursor_visible_)
return;
@@ -223,13 +224,13 @@ void LyXScreen::redraw(BufferView & bv, 
 {
greyed_out_ = false;
workarea().getPainter().start();
-   hideCursor();
+   sync_allowed_ = false;
paintText(bv, vi);
lyxerr[Debug::DEBUG] << "Redraw screen" << endl;
expose(0, 0, workarea().workWidth(), workarea().workHeight());
workarea().getPainter().end();
theCoords.doneUpdating();
-   showCursor(bv);
+   sync_allowed_ = true;
 }
 
 
Index: screen.h
===
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/screen.h,v
retrieving revision 1.30
diff -u -p -r1.30 screen.h
--- screen.h30 Nov 2004 01:59:46 -  1.30
+++ screen.h9 May 2005 06:21:34 -
@@ -86,6 +86,9 @@ private:
 
/// is the cursor currently displayed
bool cursor_visible_;
+
+   ///
+   bool sync_allowed_;
 };
 
 #endif // SCREEN_H


pgpslJ6Q4voWc.pgp
Description: PGP signature