g_signal delays (C, GTK+) - c

I've got a little GTK-Application with two buttons (A, B) and a drawing area (C).
When I click on A, C's size should be recalculated and set with gtk_widget_set_size_request(). This will cause an expose-event, whose handler will calculate some data. Further, the click on A will emit a clicked signal at B, whose handler needs the data calculated by C's expose-event.
In fact everything works fine, but the expose-event delays somehow, and the clicked handler is called before and the data (you may guess it) is missing.
a_handler() {
new_size = calculate_size();
gtk_widget_set_size_request(C, new_size); //Will cause expose-event
g_signal_emit_by_name(B, "clicked");
}
b_handler() {
calculate_something(data); //Error
}
c_handler() {
draw_something();
data = calcluate_data();
}
What can I do?

Gtk (and most other GUI toolkits) does the painting and event handling all in one thread. Therefore when the expose event is emitted, it goes into a queue and will be handled only after a_handler returns.
The best approach in my opinion would be to move the calculation somewhere else, if there is not some good reason to tie it into GUI drawing. For example, there could be a separate method calculate_data that is called both from b_handler and c_handler.
The next best way is to call gdk_window_process_updates to force the expose event to be handled immediately:
http://developer.gnome.org/gdk/stable/gdk-Windows.html#gdk-window-process-updates

The ugly fix is typically to add calls to gtk_main_iteration(), for instance between the call to gtk_widget_set_size_request() and the signal-emission.

Related

X11 drawing on resize [duplicate]

I'm writing a program that has an X11/Xlib interface, and my event processing loop looks like this:
while (XNextEvent(display, &ev) >= 0) {
switch (ev.type) {
// Process events
}
}
The problem is when the window is resized, I get a bunch of Expose events telling me which parts of the window to redraw. If I redraw them in direct response to the events, the redraw operation lags terribly because it is so slow (after resizing I get to see all the newly invalidated rectangles refresh one by one.)
What I would like to do is to record the updated window size as it changes, and only run one redraw operation on the entire window (or at least only two rectangles) when there are no more events left to process.
Unfortunately I can't see a way to do this. I tried this:
do {
XPeekEvent(display, &ev);
while (XCheckMaskEvent(display, ExposureMask | StructureNotifyMask, &ev)) {
switch (ev.type) {
// Process events, record but don't process redraw events
}
}
// No more events, do combined redraw here
}
Which does actually work, but it's a little inefficient, and if an event arrives that I am not interested in the XCheckMaskEvent call doesn't remove it from the queue, so it stays there stopping XPeekEvent from blocking, resulting in 100% CPU use.
I was just wondering whether there is a standard way to achieve the delayed/combined redraw that I am after? Many of the Xlib event processing functions seem to block, so they're not really suitable to use if you want to do some processing just before they block, but only if they would block!
EDIT: For the record, this is the solution I used. It's a simplified version of n.m.'s:
while (XNextEvent(display, &ev) >= 0) {
switch (ev.type) {
// Process events, remember any redraws needed later
}
if (!XPending(display)) {
// No more events, redraw if needed
}
}
FWIW a UI toolkit such as GTK+ does it this way:
for each window, maintains a "damage region" (union of all expose events)
when the damage region becomes non-empty, adds an "idle handler" which is a function the event loop will run when it doesn't have anything else to do
the idle handler will run when the event queue is empty AND the X socket has nothing to read (according to poll() on ConnectionNumber(dpy))
the idle handler of course repaints the damage region
In GTK+, they're changing this over to a more modern 3D-engine oriented way (clean up the damage region on vertical sync) in a future version, but it's worked in the fairly simple way above for many years.
When translated to raw Xlib, this looks about like n.m.'s answer: repaint when you have a damage region and !XPending(). So feel free to accept that answer I just figured I'd add a little extra info.
If you wanted things like timers and idles, you could consider something lke libev http://software.schmorp.de/pkg/libev.html it's designed to just drop a couple of source files in your app (it isn't set up to be an external dependency). You would add the display's file descriptor to the event loop.
For tracking damage regions, people often cut-and-paste the file "miregion.c" which is from the "machine independent" code in the X server. Just google for miregion.c or download the X server sources and look for it. A "region" here is simply a list of rectangles which supports operations such as union and intersect. To add damage, union it with the old region, to repair damage, subtract it, etc.
Try something like the following (not actually tested):
while (TRUE) {
if (XPending(display) || !pendingRedraws) {
// if an event is pending, fetch it and process it
// otherwise, we have neither events nor pending redraws, so we can
// safely block on the event queue
XNextEvent (display, &ev);
if (isExposeEvent(&ev)) {
pendingRedraws = TRUE;
}
else {
processEvent(&ev);
}
}
else {
// we must have a pending redraw
redraw();
pendingRedraws = FALSE;
}
}
It could be beneficial to wait for 10 ms or so before doing the redraw. Unfortunately the raw Xlib has no interface for timers. You need a higher-level toolkit for that (all toolkits including Xt have some kind of timer interface), or work directly with the underlying socket of the X11 connection.

RxJS DOM pause observable while another "is dragging"?

UPDATE
I've tried to make a standalone version here: https://codepen.io/neezer/pen/pPRJar
It doesn't work quite like my local copy, but I'm hoping it similar enough that you can see where I'm trying to go.
I'm not getting quite the same behavior as well because I changed the listener target to document, which seemed to help some.
Also, I'm using RxJS v5 and the latest version of React.
Still getting the hang of RxJS...
I have two Observables: one subscribed to mouseover x coordinates on a table to show a resize column, and the other to allow the user to drag on that column.
Roughly speaking, the first one looks like this (all of the below defined in a componentDidUpdate lifecycle method in a React component):
Rx.DOM.mouseover(tableEl)
.map(/* some complicated x coordinate checking */)
.distinctUntilChanged()
.subscribe(/* setState call */)
That works great, and gives me this:
So now I want to provide the actual "drag" behavior, and I tried setting up a new Observable like so
// `resizerEl` is the black element that appears on hover
// from the previous observable; it's just a div that gets
// repositioned and conditionally created
Rx.DOM.mousedown(resizerEl)
.flatMap(md => {
md.preventDefault()
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
})
.subscribe(/* do column resizing stuff */)
There are three problems with that:
Once I've done my first "drag", I can't do any more. My understanding is that takeUntil completes the Observable, and I'm not sure how I can "restart" it.
The mousemove from the first observable is still active while I'm dragging, so my black div will disappear once my x position changes enough to trigger that behavior.
The binding on the second Observable doesn't always seem to trigger (it's unreliable). I think there might be a race condition or something happening here because sometimes I'll refresh the page and I'll get the drag once (from #1), and other times I won't get it at all.
Note at first after a clean refresh I can't drag the handle (#3), then I refresh, and I can't drag the handle past the bounds setup from the first Observable--and the black resizer bar disappears and reappears as my mouse's x coordinate enters and leaves that envelope (#2).
I've been head-banging on this for quite some time now and would really appreciate any insight as to what I'm doing wrong here. In short, I want
the first Observable to "pause" when I'm dragging, then resume when I'm done dragging
the second Observable to not "complete" (or "restart") once a drag is done
the second Observable to reliably work
As I mentioned earlier, I currently have this logic setup in a React component's componentDidUpdate lifecycle method, the shape of which looks roughly like this:
componentWillUpdate() {
// bail if we don't have the ref to our table
if (!tableEl) {
return;
}
// try not to have a new Observable defined on each component update
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
// try not to have a new Observable defined on each component update
if (!this.resizerPos$) {
this.resizerPos$ = // first Observable from above
}
}
I've played around with this a bit now, I don't think this answer will be complete, but I'd like to share my insights. Hopefully a more advanced RxJS mind will chime in, and we can all work together to figure it out :).
I recreated a "lite-er" version of this in CodePen, using some light jQuery manipulation as opposed to React. Here's what I have so far:
"the first Observable to "pause" when I'm dragging, then resume when I'm done dragging"
Solving the first point helps with the other two. Based on what I had to do to get my resizerEl, I get the feeling it is rendered in the render method of the component based on something in this.state. If this is true, that means that when the first observable still has the ability to create and destroy resizerEl even while the second observable is listening. This means that resizerEl will no longer be able to generate any events, even though the observable doesn't complete until you've moused up.
In my case, I noticed that if you moved the mouse fast enough to go outside of width of what you were trying to drag, it would eliminate resizerEl, which is of what we want, but not while we're trying to drag something!
My solution: I introduced another variable to the "state" of the "component". This would set to true when we moused down on resizerEl, and then false when we moused up again.
Then we use switchMap.
Rx.DOM.mousemove(tableEl)
.switchMap(function(event) {
return this.state.mouseIsDown ? Rx.Observable.never() : Rx.Observable.of(event);
})
.map(...
There's probably a better way to do it rather than just sticking event back in an Observable, but this was the last part of it I worked on and my brain is kind of fried hehe. The key here is switching to Observable.never while the mouse is down, that way we don't go any further down the operator chain.
Actually, one nice thing is that this may not even need to be put in this.state, since that would cause a re-render. You can probably just use an instance variable, since the variable is only essential to the Observables functionality, and not any rendering. So, using this.mouseIsDown would be just as good.
How do we handle the mouse being down or up?
Part 1:
...
Rx.DOM.mousedown(resizerEl)
.do(() => this.mouseIsDown = true)
Better to abstract this to a function of course, but this is the gist of what it does.
Part 2:
...
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
.doOnCompleted(() => this.mouseIsDown = false)
Here we take advantage of doOnComplete to perform this side-effect once the observable has completed, which in this case, would be on mouseup.
"the second Observable to not "complete" (or "restart") once a drag is done"
Now here's the tricky one, I never ran into this problem. You see, every time Rx.DOM.mousedown(resizerEl) emits an event, inside of flatMap, a new Observable is created each time with return Rx.DOM.mousemove(tableEl).... I used RxJS 4.1 when making this, so it's possible that there could be behavioral differences, but I found that just because the inner observable completed didn't mean the outer one would complete as well.
So what could be happening? Well, I'm thinking that since you're using React, that resizerEl is being created/destroyed respectively when the component is rendering. I haven't seen the rest of your code of course, but please correct me if I'm wrong about this assumption.
This wasn't a problem for me because, for the sake of simplicity, I simply re-used the same element as a dragger, only hiding it when I wasn't hovering over a draggable element.
So the important question is: how is resizerEl being defined and used in your component? I'm assuming the actual reference to it is made using, well, a ref. But if it that DOM element is ever destroyed or recreated, then the Rx.Dom binding needs to be repeated all over again.
I see you're doing this with componentDidUpdate. However, the Rx.Dom.mousedown event may still be bound to an old copy of the ref to resizerEl. Even if the component destroys the resizer in the DOM, and sets the ref (I assume that is this.resizer) to null or undefined, that does not destroy the Observable that is bound to that element. In fact, I don't even think it removes it from memory, even if it's removed from the DOM! That means that this.resizerDrag$ will never evaluate to false/null, and it will still be listening to an element that is no longer in the DOM.
If that is the case, something like this in componentWillUpdate might help:
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
else if (!this.resizer && this.resizerDrag$) {
this.resizerDrag$ = null;
}
This will remove the Observable if the resizer object ceases to exist, that way we can properly reinitialise it upon it's return. There's a better to way to do with Subjects, keeping the subscription to one subject and just subscribing the subject to different mousedown streams once they become available, but let's keep this simple :).
This is something where we'd have to see the rest of your code (for this component) tell what's going on, and figure how to address it. But, my hypothesis is that you'd need to intentionally destroy the Observable if this.resizer is ever removed.
the second Observable to reliably work
Pretty sure that once the above two issues work, this one goes away. Nice and easy!
The CodePen
Here is the very naive mockup I made of this problem:
https://codepen.io/anon/pen/KmapYZ
Drag the blue circles back and forth along the X axis. (Has some little problems and bugs unrelated to the scope of this question, so I'm not worried about them.)
I made some slight changes of course just to keep it in-step with the more dumb downed approach I used. But all the concepts are there, as well as most of the code you wrote, modified to match this approach.
As I mentioned before, I didn't encounter the problem of the dragging only working once, so this better demonstrates the solution to pausing the first Observable. I re-use the dragging element, which I assume is why I didn't run into the 'drag-only-once' problem.
I hope that you or anyone else can comment with some improvements to this approach, or just show us a better (potentially more idiomatic) approach.

Animated window icon

I have seen a rare amount of programs, having animated window icons.
From a distant vantage point, this could be rather beneficially isn't it..
I took the rudder in the process of inventing one function to do so.
It does what you probably thought of and using Sleep() to simulate intervals after each "frame".
I don't have to say that using WinAPI in major programs is a bad idea as well as the fact that the program will freeze until the function terminates.
Back on track. I am looking for a possibility to avoid this behavior.
It is understandable, hence no one wants a non-functional but take a note WITH ANIMATED ICON program.
You are probably calling your function from the Main Event Loop. This is the thread where all sort of GUI events are handled, including mouse clicks and key presses. If you call Sleep from within this thread, all these processing tasks will be pending and your program will freeze.
To avoid this behavior, use g_timeout_add. This function will call a function at regular intervals from within the Main Event Loop (so no need to do it yourself). You need to define a function like this:
// define this function somewhere
gboolean animate(gpointer user_data) {
// cast user_data to appropriate type
// supposing you have a AnimationParameters class with everything you need...
AnimationParameters* animParams = (AnimationParameters*)user_data;
// update animation
// ...
return TRUE; // return TRUE to call function again, FALSE to stop
}
Elsewhere in your code, to start the animation:
AnimationParameters* animationParameters = new AnimationParameters(...);
g_timeout_add (30, // call every 30 milliseconds
animate,
animationParameters);
Hope it helps.

Multi media timer works fine in release mode but not on debug mode

I'm trying to use mmTimer with a callback function, which is a static CALLBACK function.
I know that a static function cannot call a non-static function, thanks to you all guys, except from the case where the static function gets a pointer to an object as an argument.
the weird thing is that my timer works fine in release mode, and when I try to run it in debug mode there is this unhandeled exception that pops up and breaks the program down.
void CMMTimerDlg::TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
CMMTimerDlg* p = (CMMTimerDlg*)dwUser;
if(p)
{
p->m_MMTimer += p->m_TimeDelay;
p->UpdateData(FALSE);
}
}
my questions are : - is there any way to resolve this problem? - If this error occurs on debug mode, who ensures me that it wouldn't happen once i release the program?
there is where the program stops:
#ifdef _DEBUG
void CWnd::AssertValid() const
{
if (m_hWnd == NULL)
return; // null (unattached) windows are valid
// check for special wnd??? values
ASSERT(HWND_TOP == NULL); // same as desktop
if (m_hWnd == HWND_BOTTOM)
ASSERT(this == &CWnd::wndBottom);
else if (m_hWnd == HWND_TOPMOST)
ASSERT(this == &CWnd::wndTopMost);
else if (m_hWnd == HWND_NOTOPMOST)
ASSERT(this == &CWnd::wndNoTopMost);
else
{
// should be a normal window
ASSERT(::IsWindow(m_hWnd));
// should also be in the permanent or temporary handle map
CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL);
when it gets to pMap it stops at that assertion!!!!
here is the static CALLBACK function
static void CALLBACK TimerProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
here is how I set the timer
UINT unTimerID = timeSetEvent(m_TimeDelay,1,(LPTIMECALLBACK)TimerProc,(DWORD)this,TIME_PERIODIC);
The problem here is that multimedia timer API unlike many other has restrictions on what you are allowed to do inside the callback. You are basically not allowed much and what you are allowed is to update internal structures, do some debug output, and set an synchronization event.
Remarks
Applications should not call any system-defined functions from inside
a callback function, except for PostMessage, timeGetSystemTime,
timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg,
midiOutLongMsg, and OutputDebugString.
Assertion failures start display message boxes which are not allowed and can eventually crash the process. Additionally, windowing API such as IsWindow and friends are not allowed either and are the first place cause leading further to assertion failures.
The best here is to avoid using multimedia timers at all. In most cases you have less restrictive alternate options.
It only looks like your code works in the Release build, it will not assert() that you are doing it right. And you are not doing it right.
The callback from a multi-media timer runs on an arbitrary thread-pool thread. You have to be very careful about what you do in the callback. For one, you cannot directly touch the UI, that code is fundamentally thread-unsafe. So you most certainly cannot call UpdateData(). At best, you update a variable and let the UI thread know that it needs to refresh the window. Use PostMessage(). In general you need a critical section to ensure that your callback doesn't update that variable while the UI thread is using it to update the window.
The assert you get in the Debug build suggests more trouble. Looks like you are not making sure that the timer can no longer callback when the user closes the window. That's pretty hard to solve cleanly, it is a fundamental threading race. PostMessage() will already keep you out of the worst trouble. To do it perfectly clean, you must prevent the window from closing until you know that the timer cannot callback anymore. Which requires setting an event when you get WM_CLOSE and not call DestroyWindow. The timer's callback needs to check that event, call timeKillEvent() and post another message. Which the UI thread can now use to really close the window.
Threading is hard, do make sure that SetTimer() isn't already good enough to get the job done. It certainly will be if the UI update is the only side-effect. You only need timeSetEvent() when you require an accurate timer that needs to do something that is not UI related. Human eyes just don't have that requirement. Only our ears do.

Stop a CPU-intensive operation by pressing a GTK button

I'm extending a GTK-application that does a group of operations that takes high CPU loads. I want to include the possibility to stop this operation by clicking on a button in the GUI.
The problem is that, as expected, the signal coming from the button is actually fired just after the operation is completed.
For now, the code kinda looks like this:
[...]
// code snippet to show the dialog and to enable user interactions with the buttons on the lower side of the window
while(TRUE) {
gint run = gtk_dialog_run (window_main);
if (run == GTK_RESPONSE_APPLY) {
gboolean success = start_long_operation();
}
else if (run == GTK_RESPONSE_HELP) {
open_about();
}
else if (run == GTK_RESPONSE_CANCEL) {
stop_long_operation();
}
else {
gtk_widget_destroy (window_main);
return;
}
}
I've declared a global variable busy_state that is checked by the long operation's function: if it is TRUE, simply the inner loop continues to cycle. Else, the loop exits and the function returns a result.
stop_long_operation() simply sets this global var to FALSE.
As written before, I can't press the "stop" button and "send" GTK_RESPONSE_CANCEL until the operation finishes, because it blocks the entire window.
I've tried the use of while (g_main_context_iteration(NULL, FALSE)) trick inside the stop_long_operation() function, as explained in the gtk's docs, but without results.
Do I really need to set up a multithread functionality? Can I avoid this?
Thanks for the help.
If you can break up your long operation into multiple smaller tasks you may be able to avoid using threads. The easiest way would be to just create a callback that you would pass to g_idle_add (or g_idle_add_full). Each time the callback runs it does a small amount of work, then returns TRUE. When the the task is completed, return FALSE and the callback not be run again. When you would like to interrupt the task, simply remove the callback by passing the value returned by g_idle_add to g_source_remove.
If you can't break up the operation then threads are pretty much your only choice. g_thread_new is the low-level way to do that, but it's generally easier to use a GThreadPool. A more advanced option would be to use g_simple_async_result_run_in_thread.
Here's another option if you don't want to use threads (although you should use threads and this is very insecure):
Use processes. Processes are much simpler, and can allow you some greater flexibility. Here's what you need to do:
Create another C/C++/Any language you want program that does the task
Spawn it using spawn() or popen()
(Optional) Pass arguments using the command line, or IPC
When the button is pressed, use either the kill() call on UNIX, or the Win32 kill function to kill the process. You can use SIGTERM on UNIX and register a handler so that you can have a controlled shutdown.

Resources