X11: How to delay repainting until all events are processed? - x11

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.

Related

Firefox Extension: responding to an http-on-modify-request observed in the parent with a message to the child frame responsible for the load

I'm trying to enhance an existing Firefox extension which relies on nsIContentPolicy to detect and abort certain network loads (in order to block the resulting UI action, i.e. tab navigation). Then handle loading that resource internally. Under rare circumstances, only after handling the load, it turns out we shouldn't have interrupted the load at all, so we flag it to be ignored and re-start it.
Under e10s/multi-process, that means the parent (where the content policy is running) must send a message to the child (handling the UI for the content) to restart the load. Today, that's done by:
function findMessageManager(aContext) {
// With e10s off, context is a <browser> with a direct reference to
// the docshell loaded therein.
var docShell = aContext && aContext.docShell;
if (!docShell) {
// But with e10s on, context is a content window and we have to work hard
// to find the docshell, from which we can find the message manager.
docShell = aContext
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem;
}
try {
return docShell
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
} catch (e) {
return null;
}
};
Which is crazy complex, because e10s is crazy complex. But it works; it generates some object in the parent, upon which I can call .sendAsyncMessage(), and then the addMessageListener() handler in my frame/child script receives it, and does what it needs to do.
I'd like to switch from nsIContentPolicy to http-on-modify-request as it presents more information for making a better determination (block and handle this load?) earlier. Inside that observer I can do:
var browser = httpChannel
.notificationCallbacks.getInterface(Ci.nsILoadContext)
.topFrameElement;
Which gives me an object which has a .messageManager which is some kind of message manager, and which has a .sendAsyncMessage() method. But when I use that .sendAsyncMessage(), the message disappears, never to be observed by the child.
Context: https://github.com/greasemonkey/greasemonkey/issues/2280
This should work in principle, although the docshell tree traversal may do different things in e10s and non-e10s, so you have to be careful there. In e10s rootTreeItem -> nsIContentFrameMessageManager should give you the MM equivalent to a frame script and topFrameElement.frameLoader.messageManager should give you the <browser>'s MM, which pretty much is the parent side counterpart to it.
Potential sources of confusion:
e10s on vs. off
process MM vs. frame MM hierarchy
listening in the wrong frame for the message (registering in all frames might help for debugging purposes)
This is the function I use to find the content message manager:
function contentMMFromContentWindow_Method2(aContentWindow) {
if (!gCFMM) {
gCFMM = aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
}
return gCFMM;
}
So maybe get the content window that triggered that request, and then use this function.

Synchronous XMLHttpRequest deprecated

Today, I had to restart my browser due to some issue with an extension. What I found when I restarted it, was that my browser (Chromium) automatically updated to a new version that doesn't allow synchronous AJAX-requests anymore. Quote:
Synchronous XMLHttpRequest on the main thread is deprecated because of
its detrimental effects to the end user's experience. For more help,
check http://xhr.spec.whatwg.org/.
I need synchronous AJAX-requests for my node.js applications to work though, as they store and load data from disk through a server utilizing fopen. I found this to be a very simplistic and effective way of doing things, very handy in the creation of little hobby projects and editors... Is there a way to re-enable synchronous XMLHttpRequests in Chrome/Chromium?
This answer has been edited.
Short answer:
They don't want sync on the main thread.
The solution is simple for new browsers that support threads/web workers:
var foo = new Worker("scriptWithSyncRequests.js")
Neither DOM nor global vairables aren't going to be visible within a worker but encapsulation of multiple synchronous requests is going to be really easy.
Alternative solution is to switch to async but to use browser localStorage along with JSON.stringify as a medium. You might be able to mock localStorage if you allowed to do some IO.
http://caniuse.com/#search=localstorage
Just for fun, there are alternative hacks if we want to restrict our self using only sync:
It is tempting to use setTimeout because one might think it is a good way to encapsulate synchronous requests together. Sadly, there is a gotcha. Async in javascript doesn't mean it gets to run in its own thread. Async is likely postponing the call, waiting for others to finish. Lucky for us there is light at the end of the tunnel because it is likely you can use xhttp.timeout along with xhttp.ontimeout to recover. See Timeout XMLHttpRequest
This means we can implement tiny version of a schedular that handles failed request and allocates time to try again or report error.
// The basic idea.
function runSchedular(s)
{
setTimeout(function() {
if (s.ptr < callQueue.length) {
// Handles rescheduling if needed by pushing the que.
// Remember to set time for xhttp.timeout.
// Use xhttp.ontimeout to set default return value for failure.
// The pushed function might do something like: (in pesudo)
// if !d1
// d1 = get(http...?query);
// if !d2
// d2 = get(http...?query);
// if (!d1) {pushQue tryAgainLater}
// if (!d2) {pushQue tryAgainLater}
// if (d1 && d2) {pushQue handleData}
s = s.callQueue[s.ptr++](s);
} else {
// Clear the que when there is nothing more to do.
s.ptr = 0;
s.callQueue = [];
// You could implement an idle counter and increase this value to free
// CPU time.
s.t = 200;
}
runSchedular(s);
}, s.t);
}
Doesn't "deprecated" mean that it's available, but won't be forever. (I read elsewhere that it won't be going away for a number of years.) If so, and this is for hobby projects, then perhaps you could use async: false for now as a quick way to get the job done?

What is considered overloading the main thread?

I am displaying information from a data model on a user interface. My current approach to doing so is by means of delegation as follows:
#protocol DataModelDelegate <NSObject>
- (void)updateUIFromDataModel;
#end
I am implementing the delegate method in my controller class as follows, using GCD to push the UI updating to the main thread:
- (void)updateUIFromDataModel {
dispatch_async(dispatch_get_main_queue(), ^{
// Code to update various UI controllers
// ...
// ...
});
}
What I am concerned about is that in some situations, this method can be called very frequently (~1000 times per second, each updating multiple UI objects), which to me feels very much like I am 'spamming' the main thread with commands.
Is this too much to be sending to the main thread? If so does anyone have any ideas on what would be the best way of approaching this?
I have looked into dispatch_apply, but that appears to be more useful when coalescing data, which is not what I am after - I really just want to skip updates if they are too frequent so only a sane amount of updates are sent to the main thread!
I was considering taking a different approach and implementing a timer instead to constantly poll the data, say every 10 ms, however since the data updating tends to be sporadic I feel that it would be wasteful to do so.
Combining both approaches, another option I have considered would be to wait for an update message and respond by setting the timer to poll the data at a set interval, and then disabling the timer if the data appears to have stopped changing. But would this be over-complicating the issue, and would the sane approach be to simply have a constant timer running?
edit: Added an answer below showing the adaptations using a dispatch source
One option is to use a Dispatch Source with type DISPATCH_SOURCE_TYPE_DATA_OR which lets you post events repeatedly and have libdispatch combine them together for you. When you have something to post, you use dispatch_source_merge_data to let it know there's something new to do. Multiple calls to dispatch_source_merge_data will be coalesced together if the target queue (in your case, the main queue) is busy.
I have been experimenting with dispatch sources and got it working as expected now - Here is how I have adapted my class implementation in case it is of use to anyone who comes across this question:
#implementation AppController {
#private
dispatch_source_t _gcdUpdateUI;
}
- (void)awakeFromNib {
// Added the following code to set up the dispatch source event handler:
_gcdUpdateUI = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0,
dispatch_get_main_queue());
dispatch_source_set_event_handler(_gcdUpdateUI, ^{
// For each UI element I want to update, pull data from model object:
// For testing purposes - print out a notification:
printf("Data Received. Messages Passed: %ld\n",
dispatch_source_get_data(_gcdUpdateUI));
});
dispatch_resume(_gcdUpdateUI);
}
And now in the delegate method I have removed the call to dispatch_async, and replaced it with the following:
- (void)updateUIFromDataModel {
dispatch_source_merge_data(_gcdUpdateUI, 1);
}
This is working absolutely fine for me. Now Even during the most intense data updating the UI stays perfectly responsive.
Although the printf() output was a very crude way of checking if the coalescing is working, a quick scrolling back up the console output showed me that the majority of the messages print outs had a value 1 (easily 98% of them), however there were the intermittent jumps to around 10-20, reaching a peak value of just over 100 coalesced messages around a time when the model was sending the most update messages.
Thanks again for the help!
If the app beach-balls under heavy load, then you've blocked the main thread for too long and you need to implement a coalescing strategy for UI updates. If the app remains responsive to clicks, and doesn't beach-ball, then you're fine.

Can someone explain callback/event firing

In a previous SO question it was recommended to me to use callback/event firing instead of polling. Can someone explain this in a little more detail, perhaps with references to online tutorials that show how this can be done for Java based web apps.
Thanks.
The definition of a callback from Wikipedia is:
In computer programming, a callback is
executable code that is passed as an
argument to other code. It allows a
lower-level software layer to call a
subroutine (or function) defined in a
higher-level layer.
In it's very basic form a callback could be used like this (pseudocode):
void function Foo()
{
MessageBox.Show("Operation Complete");
}
void function Bar(Method myCallback)
{
//Perform some operation
//When completed execute the callback method
myCallBack().Invoke();
}
static int Main()
{
Bar(Foo); //Pops a message box when Bar is completed
}
Modern languages like Java and c# have a standardized way of doing this and they call it events. An event is simply a special type of property added to a class that contains a list of Delegates / Method Pointers / Callbacks (all three of these things are the same thing. When the event gets "fired" it simply iterates through it's list of callbacks and executes them. These are also referred to as listeners.
Here's an example
public class Button
{
public event Clicked;
void override OnMouseUp()
{
//User has clicked on the button. Let's notify anyone listening to this event.
Clicked(); //Iterates through all the callbacks in it's list and calls Invoke();
}
}
public class MyForm
{
private _Button;
public Constructor()
{
_Button = new Button();
//Different languages provide different ways of registering listeners to events.
// _Button.Clicked += Button_Clicked_Handler;
// _Button.Clicked.AddListener(Button_Clicked_Handler);
}
public void Button_Clicked_Handler()
{
MessageBox.Show("Button Was Clicked");
}
}
In this example the Button class has an event called Clicked. It allows anyone who wants to be notified when is clicked to register a callback method. In this case the "Button_Clicked_Handler" method would be executed by Clicked event.
Eventing/Callback architecture is very handy whenever you need to be notified that something has occurred elsewhere in the program and you have no direct knowledge of when or how this happens.
This greatly simplifies notification. Polling makes it much more difficult because you are responsible for checking every so often whether or not an operation has completed. A simple polling mechanism would be like this:
static void CheckIfDone()
{
while(!Button.IsClicked)
{
//Sleep
}
//Button has been clicked.
}
The problem is that this particular situation would block your existing thread and have to continue checking until Button.IsClicked is true. The nice thing about eventing architecture is that it is asynchronous and let's the Acting Item (button) notify the listener when it is completed instead of the listener having to keep checking,
The difference between polling and callback/event is simple:
Polling: You are asking, continuously or every fixed amount of time, if some condition is meet, for example, if some keyboard key have been pressed.
Callback: You say to some driver, other code or whatever: When something happens (the keyboard have been pressed in our example), call this function, and you pass it what function you want to be called when the event happens. This way, you can "forget" about that event, knowing that it will be handled correctly when it happens.
Callback is when you pass a function/object to be called/notified when something it cares about happens. This is used a lot in UI - A function is passed to a button that is called whenever the button is pressed, for example.
There are two players involved in this scenario. First you have the "observed" which from time to time does things in which other players are interested. These other players are called "observers". The "observed" could be a timer, the "observers" could be tasks, interested in alarm events.
This "pattern" is described in the book "Design Patterns, Elements of Reusable Object-Oriented Software" by Gamma, Helm, Johnson and Vlissides.
Two examples:
The SAX parser to parse XML walks
trough an XML file and raises events
each time an element is encountered.
A listener can listen to these
elements and do something with it.
Swing and AWT are based on this
pattern. When the user moves the
mouse, clicks or types something on
the keyboard, these actions are
converted into events. The UI
components listen to these
events and react to them.
Being notified via an event is almost always preferable to polling, especially if hardware is involved and that event originates from a driver issuing a CPU interrupt. In that case, you're not using ANY cpu at all while you wait for some piece of hardware to complete a task.

Modal operation using IMessageFilter and DoEvents

This is a Windows Forms application. I have a function which captures some mouse events modally till a condition is met. For example, I would like to wait for the user to select a point in the window's client area (or optionally cancel the operation using the Escape key) before the function returns. I am using the following structure:
Application::AddMessageFilter(someFilter);
while(someFilter->HasUserSelectedAPoint_Or_HitEscapeKey()){
Application::DoEvents();
}
Application::RemoveMessageFilter(someFilter);
This works quite nicely except for taking up nearly 100% CPU usage when control enters the while loop. I am looking for an alternative similar to what is shown below:
Application::AddMessageFilter(someFilter);
while(someFilter->HasUserSelectedAPoint_Or_HitEscapeKey()){
// Assuming that ManagedGetMessage() below is a blocking
// call which yields control to the OS
if(ManagedGetMessage())
Application::DoEvents();
}
Application::RemoveMessageFilter(someFilter);
What is the right way to use IMessageFilter and DoEvents? How do I surrender control to the OS till a message is received? Any GetMessage equivalent in the managed world?
You could sleep the thread for 500ms or so between DoEvents() calls. Experiment with different values to see what feels right.

Resources