X Events in a Status Bar

Hi, I'm fighting with my personal ignorance and intellectual limitations without seeing any end. Supposed you have a window that displays a string that is the concatenation of a list (of unknown length) of MVars, written by forked threads with unknown frequencies. You could check if any single variable has been updated after a given amount of time, but it is quite probable that some of them have been updated in that period of time. So you just end up reading them periodically, and displaying what can be displayed. This stupid reading happens in a recursive loop. Now, how can you handle X Events in such a situation and specifically an Exposure event? You could stop the loop and wait for the event to occur, but you need to update the display since some MVar have change in the meantime. You could wait for the event for some time and then update anyway. It's a less stupid way of reading, but I cannot find any function to achieve this result. You could just forget about it, keep on updating periodically, but then someone is going to say that your status bar has refresh issues (who cares? Once I started it I'm not going to cover it, so no Exposure event handling is needed here. If you have a problem with that send a patch, it could even be applied...;-). Actually I think I'm not able to find a working solution in a limited amount of time, no matter how huge that amount is. But since I keep reading that in order to code Haskell you must be very smart, I thought I could ask here, before giving up...;-) Ciao Andrea

* Andrea Rossato (mailing_list@istitutocolli.org) wrote:
Now, how can you handle X Events in such a situation and specifically an Exposure event?
Well, you would keep the already rendered string in apixmap. This pixmap will be updated whenever you read a new value, actually whenever you would need to build a new string out of your list. On expose events you just copy that pixmap into the window, without any further cheks. By definition that pixmap always consists of the newest values you could get. Or did I get something wrong?
You could just forget about it, keep on updating periodically, but then someone is going to say that your status bar has refresh issues (who cares? Once I started it I'm not going to cover it, so no Exposure event handling is needed here. If you have a problem with that send a patch, it could even be applied...;-).
Hehe, as you've already seen you should not rely on that. People will always find a way to expose problems and shortcomings in software ;).
Ciao Andrea
Bye, Rob.

On Tue, Jul 17, 2007 at 01:12:16PM +0200, Robert Manea wrote:
* Andrea Rossato (mailing_list@istitutocolli.org) wrote:
Now, how can you handle X Events in such a situation and specifically an Exposure event?
Well, you would keep the already rendered string in apixmap.
This pixmap will be updated whenever you read a new value, actually whenever you would need to build a new string out of your list.
On expose events you just copy that pixmap into the window, without any further cheks.
By definition that pixmap always consists of the newest values you could get.
Or did I get something wrong?
perhaps my description was unclear. The string to be displayed is updated according to a configurable frequency (default 1 sec.), with or without an Expose event. For instance, in dzen you have a "while running handle_xev()", and handle_xev is a case analysis ("switch case Exposure" etc etc). Now, as far as I know, dzen receives a string and prints it. Now, my loop is: "while running": 1. readVariablesSetByOtherThreads() 2. printVariablesInPixmap 3. copyPixmapToWindow 4. start reading again. That is to, I cannot use XNextEvent because that is going to stop my thread since a new expose event is read. Now can I intercept an Expose event without XNextEvent()? Or, is there a function like XNextEvent that takes a timeout argument? Thanks for your kind attention (as usual!). Andrea

* Andrea Rossato (mailing_list@istitutocolli.org) wrote:
For instance, in dzen you have a "while running handle_xev()", and handle_xev is a case analysis ("switch case Exposure" etc etc).
Now, as far as I know, dzen receives a string and prints it.
Well no, actually it's more like: while(we're running) sd = watch(stdin); xd = watch(X descriptor); select(sd, xd); -- we block here until there is sth. to do if(sd) handle(stdin) - read the line and write it to a buffer if(xd) handle(X events) - get the buffer's contents and - render them to a pixmap and - render them to screen So if we receive requests on xd we can just generate or copy the pixmaps to the actual window while still using blocking functions like read() and XNextEvent().
Now, my loop is: "while running": 1. readVariablesSetByOtherThreads() 2. printVariablesInPixmap 3. copyPixmapToWindow 4. start reading again.
Ok, so there are at least 2 possible solutions: - Have all the X stuff in a separate thread which can block - Use some signaling to inform the thread there is new data
Now can I intercept an Expose event without XNextEvent()? Or, is there a function like XNextEvent that takes a timeout argument?
No timeout for XNextEvent(), though there are a couple of non-blocking functions to retrieve the events like XPending().
Thanks for your kind attention (as usual!).
Andrea
Bye, Rob.

On Tue, Jul 17, 2007 at 02:12:15PM +0200, Robert Manea wrote:
- Have all the X stuff in a separate thread which can block - Use some signaling to inform the thread there is new data
I did a mix of the two: before blocking the main thread with XNextEvent I create a background thread. This will wait for the configured interval and then will send an expose event to the window, which will unblock XNextEvent. Since the window's event_mask includes only Expose, I'm not even capturing the Event. Sound hackish, too hackish, but I did not find a quicker way. What do you think? thanks for your help. andrea the code just for reference -- | The event loop eventLoop :: Xbar () eventLoop = do c <- ask s <- get io $ forkIO $ sendUpdateMsg (display s) (window s) (refresh c) action <- io $ allocaXEvent $ \e -> do nextEvent (display s) e -- just wait... return updateWin -- ok, it's time action eventLoop sendUpdateMsg :: Display -> Window -> Int -> IO () sendUpdateMsg dpy w d = do tenthSeconds d allocaXEvent $ \e -> do setEventType e expose sendEvent dpy w False noEventMask e sync dpy False
participants (2)
-
Andrea Rossato
-
Robert Manea