I have a GTK app with a thread monitoring a COM port for particular
input events. What's the best way to notify the main GTK thread of
these events? Can i hook into the main loop somehow?
Clifford Heath.
I have a GTK app with a thread monitoring a COM port for particular
input events. What's the best way to notify the main GTK thread of
these events? Can i hook into the main loop somehow?
Clifford Heath.
Ok, I learnt some more, and I think I'm hung up on a GTK "feature".
This is with the Debian Linux version that calls itself 0.9.1.
My asynchronous device events cause a condition variable to get
set. I've written a main loop that checks the variable, like this:
while true
processEvent if (@device_event)
Gtk.main_iteration
end
(According to the documentation, I should use:
break if Gtk.main_iteration
but in this version, main_iteration always returns true. I guess
that's a change from the 0.9.1 version.)
In case there are no GUI events, I added a timeout which pumps
the loop. If the timeout is set to 1000ms, 500ms, no problem.
As soon as I drop the timeout much more (like 250ms or, what I'd
like, 100ms) the display never gets refreshed.
It seems that Gtk.main_iteration doesn't seem to ever process
paint (expose) events if an event has occurred recently, including
a timeout event(!).
What I'd like is to inject a NULL event into Gtk's queue when
an asynchronous event occurs, instead of using timeouts. But if
I can just get the timeout down to 100ms, that would work also.
Anyone have a solution to this? I wish the Debian packages weren't
always so far behind :-(.
Clifford Heath.
Hi,
Ok, I learnt some more, and I think I'm hung up on a GTK "feature".
This is with the Debian Linux version that calls itself 0.9.1.My asynchronous device events cause a condition variable to get
set. I've written a main loop that checks the variable, like this:while true
processEvent if (@device_event)
Gtk.main_iteration
end(According to the documentation, I should use:
break if Gtk.main_iteration
Do you mean to call Gtk.events_pending? ?
but in this version, main_iteration always returns true. I guess
that's a change from the 0.9.1 version.)
Hmm. I've not change the behavior of Gtk.main_iteration for long time.
Anyway, if you don't call Gtk.main anywhere, Gtk.main_iteration
doesn't work correctly.
In case there are no GUI events, I added a timeout which pumps
the loop. If the timeout is set to 1000ms, 500ms, no problem.
As soon as I drop the timeout much more (like 250ms or, what I'd
like, 100ms) the display never gets refreshed.
It seems that Gtk.main_iteration doesn't seem to ever process
paint (expose) events if an event has occurred recently, including
a timeout event(!).
Anyone have a solution to this? I wish the Debian packages weren't
always so far behind :-(.
How about to use Gtk.timeout_add ?
P.S.
I think gtk-demo(in Ruby-GNOME2 tar ball) scripts may be helpful.
On Mon, 15 Aug 2005 22:11:13 +0900 Clifford Heath <no@spam.please.net> wrote:
--
.:% Masao Mutoh<mutoh@highway.ne.jp>
Masao Mutoh wrote:
Do you mean to call Gtk.events_pending? ?
No, I'm happy if it blocks inside main_iteration, as long as the
timeout I added makes main_iteration return - which it does.
but in this version, main_iteration always returns true. I guess
that's a change from the 0.9.1 version.)Hmm. I've not change the behavior of Gtk.main_iteration for long time.
Well, then either the documentation or the code is wrong, because it
always returns true. I don't see how I can tell when quit has been
called...?
Anyway, if you don't call Gtk.main anywhere, Gtk.main_iteration
doesn't work correctly.
Ouch! I can't do that, I don't think. What is the effect if main
never gets called?
In case there are no GUI events, I added a timeout which pumps
the loop.How about to use Gtk.timeout_add ?
That's what I did, I just didn't want to confuse the issue with too
much code. A bigger snippet of what I'm doing follows:
device_change = false
Gtk.timeout_add(500) {
return true if (@busy)
device_change = true if checkDevice
true
}
while true
if device_change
processDeviceChange
device_change = false
end
puts "iteration"
p Gtk.main_iteration
end
If the timeout is set to 500 or more, all works well. If I set it to
250 or less, then the GUI doesn't refresh, even though "iteration" is
printed continuously.
Ok, I see what I need to do. Where I call main_iteration, I have to
continue calling it while events_pending?, before looping to check
for a device_change again. That seems to work better! I should've
realised.
The reason I'm doing all this is because I don't want the "process"
to occur in the middle of a flurry of GUI events, but at the end.
If I add an "idle" callback, I'll have the problem that it will chew
CPU. For an app that uses idle not to busy wait, should it call
main_iteration once to block before returning? What I really want is
a method that says "wait until the next event", but I can't see one
inthe documentation.
Also, I moved my Debian installation to "unstable", from "testing",
and I find I now have ruby-gnome2 version 1.13.0, yaay!
P.S.
I think gtk-demo(in Ruby-GNOME2 tar ball) scripts may be helpful.
I'll check that out, thanks.
Clifford Heath.
Hi,
That's what I did, I just didn't want to confuse the issue with too
much code. A bigger snippet of what I'm doing follows:device_change = false
Gtk.timeout_add(500) {
return true if (@busy)
device_change = true if checkDevice
true
}
while true
if device_change
processDeviceChange
device_change = false
end
puts "iteration"
p Gtk.main_iteration
end
Usually, we use Gtk.timeout_add with
Gtk.main something like as:
Gtk.timeout_add(500) {
return true if (@busy)
if checkDevice
processDeviceChange
end
true
}
Gtk.main
It's not good idea to make mainloop by yourself.
If you really need it, you need to learn GLib/GTK mainloops
seriously. Though I don't recommand it.
On Tue, 16 Aug 2005 08:26:15 +0900 Clifford Heath <no@spam.please.net> wrote:
--
.:% Masao Mutoh<mutoh@highway.ne.jp>
Masao Mutoh wrote:
Usually, we use Gtk.timeout_add with
Gtk.main something like as:
Ok, I considered that, but since the external input will cause
various updates to GUI objects which might not be in a stable
state, I thought it would be better to delay it, which is why
I wrote:
: The reason I'm doing all this is because I don't want the "process"
: to occur in the middle of a flurry of GUI events, but at the end.
It's not good idea to make mainloop by yourself.
If you really need it, you need to learn GLib/GTK mainloops seriously. Though I don't recommand it.
Ok, I believe you. I've built such things before. There should be
a warning like this in the documentation BTW. It'd be good if some
indication of the possible consequences was offered, too.
Thanks for your help.
Clifford Heath.