def handleMouse(self, info): """Mouse handling is a special case. The getch() curses function will signal the existence of a mouse event, but the event must be fetched and parsed separately.""" (id, mouseCol, mouseRow, mouseZ, bState) = info[0] app.log.mouse() eventTime = info[1] rapidClickTimeout = .5 def findWindow(parent, mouseRow, mouseCol): for window in reversed(parent.zOrder): if window.contains(mouseRow, mouseCol): return findWindow(window, mouseRow, mouseCol) return parent window = findWindow(self, mouseRow, mouseCol) if window == self: app.log.mouse('click landed on screen') return if self.focusedWindow != window and window.isFocusable: app.log.debug('before change focus') window.changeFocusTo(window) app.log.debug('after change focus') mouseRow -= window.top mouseCol -= window.left app.log.mouse(mouseRow, mouseCol) app.log.mouse("\n", window) #app.log.info('bState', app.curses_util.mouseButtonName(bState)) if bState & curses.BUTTON1_RELEASED: app.log.mouse(bState, curses.BUTTON1_RELEASED) if self.priorClick + rapidClickTimeout <= eventTime: window.mouseRelease(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) elif bState & curses.BUTTON1_PRESSED: if (self.priorClick + rapidClickTimeout > eventTime and self.clickedNearby(mouseRow, mouseCol)): self.clicks += 1 self.priorClick = eventTime if self.clicks == 2: window.mouseDoubleClick(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) else: window.mouseTripleClick(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) self.clicks = 1 else: self.clicks = 1 self.priorClick = eventTime self.priorClickRowCol = (mouseRow, mouseCol) window.mouseClick(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) elif bState & curses.BUTTON2_PRESSED: window.mouseWheelUp(bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) elif bState & curses.BUTTON4_PRESSED: if self.savedMouseX == mouseCol and self.savedMouseY == mouseRow: window.mouseWheelDown(bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) else: if self.savedMouseWindow and self.savedMouseWindow is not window: mouseRow += window.top - self.savedMouseWindow.top mouseCol += window.left - self.savedMouseWindow.left window = self.savedMouseWindow window.mouseMoved(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) elif bState & curses.REPORT_MOUSE_POSITION: #app.log.mouse('REPORT_MOUSE_POSITION') if self.savedMouseX == mouseCol and self.savedMouseY == mouseRow: # This is a hack for dtterm on Mac OS X. window.mouseWheelUp(bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) else: if self.savedMouseWindow and self.savedMouseWindow is not window: mouseRow += window.top - self.savedMouseWindow.top mouseCol += window.left - self.savedMouseWindow.left window = self.savedMouseWindow window.mouseMoved(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) else: app.log.mouse('got bState', app.curses_util.mouseButtonName(bState), bState) self.savedMouseWindow = window self.savedMouseX = mouseCol self.savedMouseY = mouseRow
def handleMouse(self, info): """Mouse handling is a special case. The getch() curses function will signal the existence of a mouse event, but the event must be fetched and parsed separately.""" (_, mouseCol, mouseRow, _, bState) = info[0] app.log.mouse() eventTime = info[1] rapidClickTimeout = .5 def findWindow(parent, mouseRow, mouseCol): for window in reversed(parent.zOrder): if window.contains(mouseRow, mouseCol): return findWindow(window, mouseRow, mouseCol) return parent window = findWindow(self, mouseRow, mouseCol) if window == self: app.log.mouse('click landed on screen') return if self.focusedWindow != window and window.isFocusable: app.log.debug('before change focus') window.changeFocusTo(window) app.log.debug('after change focus') mouseRow -= window.top mouseCol -= window.left app.log.mouse(mouseRow, mouseCol) app.log.mouse("\n", window) button1WasDown = self.savedMouseButton1Down self.savedMouseButton1Down = False #app.log.info('bState', app.curses_util.mouseButtonName(bState)) if bState & curses.BUTTON1_RELEASED: if button1WasDown: app.log.mouse(bState, curses.BUTTON1_RELEASED) if self.priorClick + rapidClickTimeout <= eventTime: window.mouseRelease(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) #else: # signal.setitimer(signal.ITIMER_REAL, rapidClickTimeout) else: # Some terminals (linux?) send BUTTON1_RELEASED after moving the mouse. # Specifically if the terminal doesn't use button 4 for mouse movement. # Mouse drag or mouse wheel movement done. pass elif bState & curses.BUTTON1_PRESSED: self.savedMouseButton1Down = True if (self.priorClick + rapidClickTimeout > eventTime and self.clickedNearby(mouseRow, mouseCol)): self.clicks += 1 self.priorClick = eventTime if self.clicks == 2: window.mouseDoubleClick(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) else: window.mouseTripleClick(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) self.clicks = 1 else: self.clicks = 1 self.priorClick = eventTime self.priorClickRowCol = (mouseRow, mouseCol) window.mouseClick(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) elif bState & curses.BUTTON2_PRESSED: window.mouseWheelUp(bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) elif bState & (curses.BUTTON4_PRESSED | curses.REPORT_MOUSE_POSITION): # Notes from testing: # Mac seems to send BUTTON4_PRESSED during mouse move; followed by # BUTTON4_RELEASED. # Linux seems to send REPORT_MOUSE_POSITION during mouse move; followed by # BUTTON1_RELEASED. if self.savedMouseX == mouseCol and self.savedMouseY == mouseRow: if bState & curses.REPORT_MOUSE_POSITION: # This is a hack for dtterm mouse wheel on Mac OS X. window.mouseWheelUp(bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) else: # This is the normal case: window.mouseWheelDown(bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) else: if self.savedMouseWindow and self.savedMouseWindow is not window: mouseRow += window.top - self.savedMouseWindow.top mouseCol += window.left - self.savedMouseWindow.left window = self.savedMouseWindow window.mouseMoved(mouseRow, mouseCol, bState & curses.BUTTON_SHIFT, bState & curses.BUTTON_CTRL, bState & curses.BUTTON_ALT) elif bState & curses.BUTTON4_RELEASED: # Mouse drag or mouse wheel movement done. pass else: app.log.mouse('got bState', app.curses_util.mouseButtonName(bState), bState) self.savedMouseWindow = window self.savedMouseX = mouseCol self.savedMouseY = mouseRow