+ /**
+ * Peek at certain application-level events, add to eventQueue, and wake
+ * up the consuming Thread.
+ *
+ * @param event the input event to consume
+ */
+ private void metaHandleEvent(final TInputEvent event) {
+
+ if (debugEvents) {
+ System.err.printf(String.format("metaHandleEvents event: %s\n",
+ event)); System.err.flush();
+ }
+
+ if (quit) {
+ // Do no more processing if the application is already trying
+ // to exit.
+ return;
+ }
+
+ // Special application-wide events -------------------------------
+
+ // Abort everything
+ if (event instanceof TCommandEvent) {
+ TCommandEvent command = (TCommandEvent) event;
+ if (command.equals(cmAbort)) {
+ exit();
+ return;
+ }
+ }
+
+ synchronized (drainEventQueue) {
+ // Screen resize
+ if (event instanceof TResizeEvent) {
+ TResizeEvent resize = (TResizeEvent) event;
+ synchronized (getScreen()) {
+ if ((System.currentTimeMillis() - screenResizeTime >= 15)
+ || (resize.getWidth() < getScreen().getWidth())
+ || (resize.getHeight() < getScreen().getHeight())
+ ) {
+ getScreen().setDimensions(resize.getWidth(),
+ resize.getHeight());
+ screenResizeTime = System.currentTimeMillis();
+ }
+ desktopBottom = getScreen().getHeight() - 1;
+ if (hideStatusBar) {
+ desktopBottom++;
+ }
+ mouseX = 0;
+ mouseY = 0;
+ oldMouseX = 0;
+ oldMouseY = 0;
+ }
+ if (desktop != null) {
+ desktop.setDimensions(0, 0, resize.getWidth(),
+ resize.getHeight() - (hideStatusBar ? 0 : 1));
+ desktop.onResize(resize);
+ }
+
+ // Change menu edges if needed.
+ recomputeMenuX();
+
+ // We are dirty, redraw the screen.
+ doRepaint();
+
+ /*
+ System.err.println("New screen: " + resize.getWidth() +
+ " x " + resize.getHeight());
+ */
+ return;
+ }
+
+ // Put into the main queue
+ drainEventQueue.add(event);
+ }
+ }
+
+ /**
+ * Dispatch one event to the appropriate widget or application-level
+ * event handler. This is the primary event handler, it has the normal
+ * application-wide event handling.
+ *
+ * @param event the input event to consume
+ * @see #secondaryHandleEvent(TInputEvent event)
+ */
+ private void primaryHandleEvent(final TInputEvent event) {
+
+ if (debugEvents) {
+ System.err.printf("%s primaryHandleEvent: %s\n",
+ Thread.currentThread(), event);
+ }
+ TMouseEvent doubleClick = null;
+
+ // Special application-wide events -----------------------------------
+
+ if (event instanceof TKeypressEvent) {
+ if (hideMouseWhenTyping) {
+ typingHidMouse = true;
+ }
+ }
+
+ // Peek at the mouse position
+ if (event instanceof TMouseEvent) {
+ typingHidMouse = false;
+
+ TMouseEvent mouse = (TMouseEvent) event;
+ if ((mouseX != mouse.getX()) || (mouseY != mouse.getY())) {
+ oldMouseX = mouseX;
+ oldMouseY = mouseY;
+ mouseX = mouse.getX();
+ mouseY = mouse.getY();
+ } else {
+ if ((mouse.getType() == TMouseEvent.Type.MOUSE_DOWN)
+ && (!mouse.isMouseWheelUp())
+ && (!mouse.isMouseWheelDown())
+ ) {
+ if ((mouse.getTime().getTime() - lastMouseUpTime) <
+ doubleClickTime) {
+
+ // This is a double-click.
+ doubleClick = new TMouseEvent(TMouseEvent.Type.
+ MOUSE_DOUBLE_CLICK,
+ mouse.getX(), mouse.getY(),
+ mouse.getAbsoluteX(), mouse.getAbsoluteY(),
+ mouse.isMouse1(), mouse.isMouse2(),
+ mouse.isMouse3(),
+ mouse.isMouseWheelUp(), mouse.isMouseWheelDown());
+
+ } else {
+ // The first click of a potential double-click.
+ lastMouseUpTime = mouse.getTime().getTime();
+ }
+ }
+ }
+
+ // See if we need to switch focus to another window or the menu
+ checkSwitchFocus((TMouseEvent) event);
+ }
+
+ // Handle menu events
+ if ((activeMenu != null) && !(event instanceof TCommandEvent)) {
+ TMenu menu = activeMenu;
+
+ if (event instanceof TMouseEvent) {
+ TMouseEvent mouse = (TMouseEvent) event;
+
+ while (subMenus.size() > 0) {
+ TMenu subMenu = subMenus.get(subMenus.size() - 1);
+ if (subMenu.mouseWouldHit(mouse)) {
+ break;
+ }
+ if ((mouse.getType() == TMouseEvent.Type.MOUSE_MOTION)
+ && (!mouse.isMouse1())
+ && (!mouse.isMouse2())
+ && (!mouse.isMouse3())
+ && (!mouse.isMouseWheelUp())
+ && (!mouse.isMouseWheelDown())
+ ) {
+ break;
+ }
+ // We navigated away from a sub-menu, so close it
+ closeSubMenu();
+ }
+
+ // Convert the mouse relative x/y to menu coordinates
+ assert (mouse.getX() == mouse.getAbsoluteX());
+ assert (mouse.getY() == mouse.getAbsoluteY());
+ if (subMenus.size() > 0) {
+ menu = subMenus.get(subMenus.size() - 1);
+ }
+ mouse.setX(mouse.getX() - menu.getX());
+ mouse.setY(mouse.getY() - menu.getY());
+ }
+ menu.handleEvent(event);
+ return;
+ }
+
+ if (event instanceof TKeypressEvent) {
+ TKeypressEvent keypress = (TKeypressEvent) event;
+
+ // See if this key matches an accelerator, and is not being
+ // shortcutted by the active window, and if so dispatch the menu
+ // event.
+ boolean windowWillShortcut = false;
+ if (activeWindow != null) {
+ assert (activeWindow.isShown());
+ if (activeWindow.isShortcutKeypress(keypress.getKey())) {
+ // We do not process this key, it will be passed to the
+ // window instead.
+ windowWillShortcut = true;
+ }
+ }
+
+ if (!windowWillShortcut && !modalWindowActive()) {
+ TKeypress keypressLowercase = keypress.getKey().toLowerCase();
+ TMenuItem item = null;
+ synchronized (accelerators) {
+ item = accelerators.get(keypressLowercase);
+ }
+ if (item != null) {
+ if (item.isEnabled()) {
+ // Let the menu item dispatch
+ item.dispatch();
+ return;
+ }
+ }
+
+ // Handle the keypress
+ if (onKeypress(keypress)) {
+ return;
+ }
+ }
+ }
+
+ if (event instanceof TCommandEvent) {
+ if (onCommand((TCommandEvent) event)) {
+ return;
+ }
+ }
+
+ if (event instanceof TMenuEvent) {
+ if (onMenu((TMenuEvent) event)) {
+ return;
+ }
+ }
+
+ // Dispatch events to the active window -------------------------------
+ boolean dispatchToDesktop = true;
+ TWindow window = activeWindow;
+ if (window != null) {
+ assert (window.isActive());
+ assert (window.isShown());
+ if (event instanceof TMouseEvent) {
+ TMouseEvent mouse = (TMouseEvent) event;
+ // Convert the mouse relative x/y to window coordinates
+ assert (mouse.getX() == mouse.getAbsoluteX());
+ assert (mouse.getY() == mouse.getAbsoluteY());
+ mouse.setX(mouse.getX() - window.getX());
+ mouse.setY(mouse.getY() - window.getY());
+
+ if (doubleClick != null) {
+ doubleClick.setX(doubleClick.getX() - window.getX());
+ doubleClick.setY(doubleClick.getY() - window.getY());
+ }
+
+ if (window.mouseWouldHit(mouse)) {
+ dispatchToDesktop = false;
+ }
+ } else if (event instanceof TKeypressEvent) {
+ dispatchToDesktop = false;
+ } else if (event instanceof TMenuEvent) {
+ dispatchToDesktop = false;
+ }
+
+ if (debugEvents) {
+ System.err.printf("TApplication dispatch event: %s\n",
+ event);
+ }
+ window.handleEvent(event);
+ if (doubleClick != null) {
+ window.handleEvent(doubleClick);
+ }
+ }
+ if (dispatchToDesktop) {
+ // This event is fair game for the desktop to process.
+ if (desktop != null) {
+ desktop.handleEvent(event);
+ if (doubleClick != null) {
+ desktop.handleEvent(doubleClick);
+ }
+ }
+ }
+ }