[comp.sys.sun] SunView - Processing whilst Iconized

tim@uunet.uu.net (Timothy J. Stone) (01/29/90)

I am trying to persuade an application to run a specific function after
the program has been iconized.  In particular, when a specific button is
pressed, I want to push the required action on a stack and do a 

	window_set(frame, FRAME_CLOSED, TRUE, 0);

and then use the interposer to catch an event AFTER the window is
iconized.

No matter how I do it, the window closes but the icon doesn't show until
after the long-running function completes even with
notify_next_event_func() and window_release_event_lock(frame).

Any ideas or code fragments would be most gratefully received.

mark@arisia.xerox.com (Mark Weiser) (02/05/90)

Timothy Stone complains:
"No matter how I do it, the window closes but the icon doesn't show until
after the long-running function completes even with
notify_next_event_func() and window_release_event_lock(frame)."

This is a common trouble.  You have to give the notifier time to run after
you tell it things.  I have a function I use all the time to schedule
something to do later.  For instance, if I want something to happen or
something to start running immediately when a window first appears, I
schedule the thing to start (using "do_with_delay", defined below) before
calling window_main_loop.

Anyway, here is the code I use.  In Timothy's case, I think he wants to
say 
	do_with_delay(very_long_running_func, 1, 0, 0);

when he get notified of iconization, rather than calling the
very_long_running_func directly.

-mark
(I use X now, but still have a head filled with Sunview knowledge).
--------------here is the code---------------------------
/*
 * Call procedure f in a little while.
 */

struct call_wrapper {
  /* Dynamically allocating a wrapper ensures unique notifier id's. */
  void (*f)();
  long arg;
};

int
  do_with_delay(f, secs, usecs, arg)
void (*f)();
int secs, usecs;
{
  Notify_value do_the_call();
  struct call_wrapper *w;
  struct itimerval timer;

  /* Sigh, so much work just to wait a bit before starting up. */
  timer.it_interval.tv_usec = 0;
  timer.it_interval.tv_sec = 0;
  timer.it_value.tv_usec = usecs;
  timer.it_value.tv_sec = secs;
  w = (struct call_wrapper *)insider_calloc(sizeof(struct call_wrapper), 1);
  w->f = f;
  w->arg = arg;
  notify_set_itimer_func(w, do_the_call,
			 ITIMER_REAL, &timer, NULL);
}

/*
 * Wrapper to make sure procedures from do_with_delay return good values
 * to the notifier.
 */
Notify_value
  do_the_call(w, which)
struct call_wrapper *w;
{
  (*(w->f))(w->arg);
  free(w);
  return NOTIFY_DONE;
}