|
From: Daniel J S. <dan...@ie...> - 2014-02-24 07:10:40
|
On 02/24/2014 12:16 AM, sfeam wrote:
> On Sunday, 23 February 2014 11:22:42 PM Daniel J Sebald wrote:
>> On 02/23/2014 10:35 PM, sfeam wrote:
>>> On Sunday, 23 February 2014 10:04:42 PM Daniel J Sebald wrote:
>>>>
>>>> // Set plot size
>>>> if (qt_setSize)
>>>> {
>>>> term->xmax = qt_oversampling*qt_setWidth;
>>>> term->ymax = qt_oversampling*qt_setHeight;
>>>> qt_setSize = false;
>>>> }
>>>>
>>>> In a separate thread, the "term->xmax =" will be done asynchronously.
>>>> Hence a mutex/wait is needed to make sure the code in the separate
>>>> thread has updated term->xmax and term->max before the core thread can
>>>> continue onward.
>>>
>>> Ah. Now I'm with you.
>>> Yeah, this is the piece of code that has changed the most in qt
>>> because nothing seems to work properly on both linux and OSX.
>>> You are quite correct that term->foo should not be referenced in
>>> this part of the terminal driver. It is supposed to return the revised
>>> font information via an event GP_fontprops. And it _was_ doing that
>>> at one point. I've now lost track of all the work-arounds and what
>>> exactly they fixed, but certainly it would be good if you can get
>>> back to the original intent. You can look at other terminal
>>> drivers as a model if needed.
>>
>> OK, thanks. I'll look that over. I think that may be the one thing
>> that isn't working yet for what I've done, i.e., some text isn't showing
>> up probably owing to the core is told the font height is zero.
>
> Let me summarize a bit of the history.
>
> - The core code and the qt_term bits of Qt are in the same process.
> Call this "inboard"
> The screen display is being managed by a separate Qt process.
> Call this "outboard"
> The inboard and outboard processes operate asynchronously.
>
> - To reserve space for some text element on the next plot, the core
> code needs to know how big the current font is so it sends a query
> to the inboard terminal driver. This request can come either via
> term->set_font() or in enhanced text mode via term->put_text.
>
> - It would be simplest if the inboard terminal driver could just reply
> immediately with the requested font metrics. No communication back
> and forth with the outboard terminal driver is required. This is what
> the Qt terminal used to do, and still does in version 4.6.
> The font size information is obtained by calling
> QFontMetrics metrics(QFont(qt_currentFontName, qt_currentFontSize));
> Since the inboard driver and the core code are in the same process,
> the inboard driver can just set term->h_char and term->v_char
> directly and that's the end of it.
>
> - Now here comes the problem. Apparently calling QFontMetrics without
> there being a full QApplication and maybe [not sure] an event
> doesn't work properly. In particular is was causing problems
> on OSX, and it was ugly even on linux.
> See the comments in version 4.6 qt_term.cpp
> // Create a QApplication without event loop for QObject's that need it,
> // namely font handling
> // A better strategy would be to transfer the font handling to the
> // QtGnuplotWidget, but it would require
> // some synchronization between the widget and the gnuplot process.
>
> - So in January Jérôme followed through on that comment and moved
> the QFontMetrics call over to the outboard driver for version 4.7.
> That simplified things in one way, but introduced a new complication.
> Now the inboard driver has to send a change font request to the
> outboard driver (a different process) and then wait for the resulting
> size information to be sent back via a QEvent. That's where
> waitforinput() and do_event() suddenly become involved where
> they hadn't been previously. It was also slower, so he later
> introduced a cache of font metrics on the inboard side but let's
> disregard that for now.
>
> - So now I gather you are working to have an event loop in the
> inboard driver again, although I've lost track of exactly why.
Hopefully to make OSX and Windows behave the same as Unix. I don't know
for sure because Qt is a big creature, but I suspect that if there is no
event loop that timers aren't guaranteed to work and who knows what
else. So by providing an event, I'm hoping Qt performs the same on all
platforms. It's just following the examples that Qt documentation gives.
> But in that case I think it makes sense to move the
> font metrics query back into the inboard driver as well.
> At which point we return to a setup in which waitforinput()
> and do_event() are not involved in font processing.
>
> So much for font handling and the involvement of enhanced text
> processing.
>
> There is a separate issue, however, that has been at the heart of
> the recent attempts to get OSX working. Information about the
> size of the display window necessarily comes from the outboard
> driver, which is a separate process. Right now this window size
> information is also passed using a GE_fontprops event, but there's no
> good reason for that. It really should have a separate event type
> to reduce confusion. But changing the name of the event wouldn't
> change the information flow in any way.
Oh, OK. Thanks. I've got the big picture now and I think we will
probably converge on something here that is about right.
I'll correct one thing in that list which is I believe the issue is not
the presence of the QApplication in the main process, but that the
QApplication cannot have an event loop. That is, one can't issue
application.exec(), because doing so will hang gnuplot while
application.exec() blocks to handle all of its realtime traffic
(signals, slots, system calls, etc). Graphics in Qt must be done in a
main thread; it can't be done in a separate thread. That leaves the Qt
graphics code to be run in a separate process. (Note, I've fixed the
process communications a bit so that there aren't these while loops that
keep trying to establish a connection to some external service.)
The QApplication issue is why I've set out to put the bulk of the
terminal interface code in a separate thread because in the separate
thread and event loop, i.e., thread.exec(), is perfectly fine. The
thread acts on its own. My preliminary code indicates there is no
problem sending signals back and forth across that thread. So, with an
event loop running in the second thread, all the timers and whatever
else should be fine--the only restriction being that graphics cannot be
done there. If it turns out OSX doesn't behave the same in the thread
that has an event loop, then something isn't right with Qt. (We'll know
soon.)
So here is what I'm aiming for right now, sort of combining everything:
MAIN PROGRAM | QTHREAD || GNUPLOT_QT
| || (outboard)
| ||
gnuplot core | QtTerminalInterface || Currently has a
QtTerminalEmitter | (active event loop) || few things we hope
(inactive event loop) | || to move back into
| || QtTerminalInterface
where the single line means separate thread and the double line means a
separate process.
OK, for the most part I'll be offline for the week.
Dan
|