/* main() for usual operation */ int tray_main(int argc, char **argv) { XEvent ev; /* Interpret those settings that need an open display */ interpret_settings(); #ifdef DEBUG ewmh_list_supported_atoms(tray_data.dpy); #endif /* Create and show tray window */ tray_create_window(argc, argv); tray_acquire_selection(); tray_show_window(); #ifndef NO_NATIVE_KDE kde_tray_init(tray_data.dpy); #endif xembed_init(); #ifndef NO_NATIVE_KDE kde_icons_update(); #endif /* Main event loop */ while ("my guitar gently wheeps") { /* This is ugly and extra dependency. But who cares? * Rationale: we want to block unless absolutely needed. * This way we ensure that stalonetray does not show up * in powertop (i.e. does not eat unnecessary power and * CPU cycles) * Drawback: handling of signals is very limited. XNextEvent() * does not if signal occurs. This means that graceful * exit on e.g. Ctrl-C cannot be implemented without hacks. */ while (XPending(tray_data.dpy) || tray_data.scrollbars_data.scrollbar_down == -1) { XNextEvent(tray_data.dpy, &ev); xembed_handle_event(ev); scrollbars_handle_event(ev); switch (ev.type) { case VisibilityNotify: LOG_TRACE(("VisibilityNotify (0x%x, state=%d)\n", ev.xvisibility.window, ev.xvisibility.state)); visibility_notify(ev.xvisibility); break; case Expose: LOG_TRACE(("Expose (0x%x)\n", ev.xexpose.window)); expose(ev.xexpose); break; case PropertyNotify: LOG_TRACE(("PropertyNotify(0x%x)\n", ev.xproperty.window)); property_notify(ev.xproperty); break; case DestroyNotify: LOG_TRACE(("DestroyNotify(0x%x)\n", ev.xdestroywindow.window)); destroy_notify(ev.xdestroywindow); break; case ClientMessage: LOG_TRACE(("ClientMessage(from 0x%x?)\n", ev.xclient.window)); client_message(ev.xclient); break; case ConfigureNotify: LOG_TRACE(("ConfigureNotify(0x%x)\n", ev.xconfigure.window)); configure_notify(ev.xconfigure); break; case MapNotify: LOG_TRACE(("MapNotify(0x%x)\n", ev.xmap.window)); map_notify(ev.xmap); break; case ReparentNotify: LOG_TRACE(("ReparentNotify(0x%x to 0x%x)\n", ev.xreparent.window, ev.xreparent.parent)); reparent_notify(ev.xreparent); break; case SelectionClear: LOG_TRACE(("SelectionClear (0x%x has lost selection)\n", ev.xselectionclear.window)); selection_clear(ev.xselectionclear); break; case SelectionNotify: LOG_TRACE(("SelectionNotify\n")); break; case SelectionRequest: LOG_TRACE(("SelectionRequest (from 0x%x to 0x%x)\n", ev.xselectionrequest.requestor, ev.xselectionrequest.owner)); break; case UnmapNotify: LOG_TRACE(("UnmapNotify(0x%x)\n", ev.xunmap.window)); unmap_notify(ev.xunmap); break; default: #if defined(DEBUG) && defined(TRACE_EVENTS) LOG_TRACE(("Unhandled event: %s, serial: %d, window: 0x%x\n", x11_event_names[ev.type], ev.xany.serial, ev.xany.window)); #endif break; } if (tray_data.terminated) goto bailout; /* Perform all periodic tasks but for scrollbars */ perform_periodic_tasks(PT_MASK_ALL & (~PT_MASK_SB)); } perform_periodic_tasks(PT_MASK_ALL); my_usleep(500000L); } bailout: LOG_TRACE(("Clean exit\n")); return 0; }
void SYSTRAY_event_filter(XEvent *e) { XEvent ev; if (!tray_data.dpy) return; ev = *e; xembed_handle_event(ev); //scrollbars_handle_event(ev); switch (ev.type) { case VisibilityNotify: LOG_TRACE(("VisibilityNotify (0x%x, state=%d)\n", ev.xvisibility.window, ev.xvisibility.state)); visibility_notify(ev.xvisibility); break; case Expose: LOG_TRACE(("Expose (0x%x)\n", ev.xexpose.window)); expose(ev.xexpose); break; case PropertyNotify: LOG_TRACE(("PropertyNotify(0x%x)\n", ev.xproperty.window)); property_notify(ev.xproperty); break; case DestroyNotify: LOG_TRACE(("DestroyNotify(0x%x)\n", ev.xdestroywindow.window)); destroy_notify(ev.xdestroywindow); break; case ClientMessage: LOG_TRACE(("ClientMessage(from 0x%x?)\n", ev.xclient.window)); client_message(ev.xclient); break; case ConfigureNotify: LOG_TRACE(("ConfigureNotify(0x%x)\n", ev.xconfigure.window)); configure_notify(ev.xconfigure); break; case MapNotify: LOG_TRACE(("MapNotify(0x%x)\n", ev.xmap.window)); map_notify(ev.xmap); break; case ReparentNotify: LOG_TRACE(("ReparentNotify(0x%x to 0x%x)\n", ev.xreparent.window, ev.xreparent.parent)); reparent_notify(ev.xreparent); break; case SelectionClear: LOG_TRACE(("SelectionClear (0x%x has lost selection)\n", ev.xselectionclear.window)); selection_clear(ev.xselectionclear); break; case SelectionNotify: LOG_TRACE(("SelectionNotify\n")); break; case SelectionRequest: LOG_TRACE(("SelectionRequest (from 0x%x to 0x%x)\n", ev.xselectionrequest.requestor, ev.xselectionrequest.owner)); break; case UnmapNotify: LOG_TRACE(("UnmapNotify(0x%x)\n", ev.xunmap.window)); unmap_notify(ev.xunmap); break; default: #if defined(DEBUG) && defined(TRACE_EVENTS) LOG_TRACE(("Unhandled event: %s, serial: %d, window: 0x%x\n", x11_event_names[ev.type], ev.xany.serial, ev.xany.window)); #endif break; } // TODO: perform_periodic_tasks(PT_MASK_ALL); #if 0 if (tray_data.terminated) goto bailout; /* Perform all periodic tasks but for scrollbars */ perform_periodic_tasks(PT_MASK_ALL & (~PT_MASK_SB)); }