def set_dock_icon(self): if self.icon_filename: debug("OSXTray.set_dock_icon() loading icon from %s", self.icon_filename) pixbuf = gtk.gdk.pixbuf_new_from_file(self.icon_filename) self.macapp.set_dock_icon_pixbuf(pixbuf) debug("OSXTray.set_dock_icon() done")
def cleanup(self): debug("Win32Tray.cleanup() tray_widget=%s", self.tray_widget) if self.tray_widget: self.stop_win32_session_events(self.getHWND()) self.tray_widget.close() self.tray_widget = None debug("Win32Tray.cleanup() ended")
def main(): import logging logging.basicConfig(format="%(asctime)s %(message)s") logging.root.setLevel(logging.DEBUG) appindicator = get_appindicator() if not appindicator: debug("appindicator not available") return if not can_use_appindicator(): debug("appindicator may not be shown...") from xpra.gtk_common.gobject_compat import import_gobject, import_gtk gobject = import_gobject() gtk = import_gtk() menu = gtk.Menu() item = gtk.MenuItem("Some Menu Item Here") menu.append(item) menu.show_all() a = AppindicatorTray(menu, "test", "xpra.png", None, None, None, gtk.main_quit) a.show() gobject.timeout_add(1000*10, gtk.main_quit) gtk.main()
def detect_win32_session_events(self, app_hwnd): """ Use pywin32 to receive session notification events. """ if app_hwnd is None: if self.tray_widget is None: #probably closing down, don't warn return log.warn("detect_win32_session_events(%s) missing handle!", app_hwnd) return try: debug("detect_win32_session_events(%s)", app_hwnd) #register our interest in those events: #http://timgolden.me.uk/python/win32_how_do_i/track-session-events.html#isenslogon #http://stackoverflow.com/questions/365058/detect-windows-logout-in-python #http://msdn.microsoft.com/en-us/library/aa383841.aspx #http://msdn.microsoft.com/en-us/library/aa383828.aspx win32ts.WTSRegisterSessionNotification( app_hwnd, win32ts.NOTIFY_FOR_THIS_SESSION) #catch all events: http://wiki.wxpython.org/HookingTheWndProc self.old_win32_proc = win32gui.SetWindowLong( app_hwnd, win32con.GWL_WNDPROC, self.MyWndProc) except Exception, e: log.error("failed to hook session notifications: %s", e)
def main(): import logging logging.basicConfig(format="%(asctime)s %(message)s") logging.root.setLevel(logging.DEBUG) appindicator = get_appindicator() if not appindicator: debug("appindicator not available") return if not can_use_appindicator(): debug("appindicator may not be shown...") from xpra.gtk_common.gobject_compat import import_gobject, import_gtk gobject = import_gobject() gtk = import_gtk() menu = gtk.Menu() item = gtk.MenuItem("Some Menu Item Here") menu.append(item) menu.show_all() a = AppindicatorTray(menu, "test", "xpra.png", None, None, None, gtk.main_quit) a.show() gobject.timeout_add(1000 * 10, gtk.main_quit) gtk.main()
def get_geometry(self): ag = self.tray_widget.get_geometry() debug("GTKStatusIconTray.get_geometry() %s.get_geometry()=%s", self.tray_widget, ag) if ag is None: #probably win32 or OSX... return self.geometry_guess _, geom, _ = ag return geom.x, geom.y, geom.width, geom.height
def get_geometry(self): ag = self.tray_widget.get_geometry() debug("GTKStatusIconTray.get_geometry() %s.get_geometry()=%s", self.tray_widget, ag) if ag is None: return None _, geom, _ = ag return geom.x, geom.y, geom.width, geom.height
def set_dock_icon(self): if not self.default_icon_filename: return filename = os.path.abspath(self.default_icon_filename) if not os.path.exists(filename): log.warn("cannot set dock icon, file '%s' not found!", filename) return debug("OSXTray.set_dock_icon() loading icon from %s", filename) pixbuf = gtk.gdk.pixbuf_new_from_file(filename) self.macapp.set_dock_icon_pixbuf(pixbuf)
def set_global_menu(self): mh = getOSXMenuHelper() if mh.build()!=self.menu: log.error("the menu (%s) is not from the menu helper!", self.menu) return #redundant: the menu bar has already been set during gui init #using the basic the simple menu from build_menu_bar() self.macapp.set_menu_bar(self.menu) mh.add_full_menu() debug("OSXTray.set_global_menu() done")
def set_dock_menu(self): #dock menu debug("OSXTray.set_dock_menu()") self.dock_menu = gtk.Menu() self.disconnect_dock_item = gtk.MenuItem("Disconnect") self.disconnect_dock_item.connect("activate", self.quit) self.dock_menu.add(self.disconnect_dock_item) self.dock_menu.show_all() self.macapp.set_dock_menu(self.dock_menu) debug("OSXTray.set_dock_menu() done")
def MyWndProc(self, hWnd, msg, wParam, lParam): assert hWnd==self.getHWND(), "invalid hwnd: %s (expected %s)" % (hWnd, self.getHWND()) if msg in IGNORE_EVENTS: debug("%s: %s / %s", IGNORE_EVENTS.get(msg), wParam, lParam) elif msg==WM_TRAY_EVENT: self.tray_event(wParam, lParam) elif msg==win32con.WM_ACTIVATEAPP: debug("WM_ACTIVATEAPP focus changed: %s / %s", wParam, lParam) else: log.warn("unexpected message: %s / %s / %s", KNOWN_WM_EVENTS.get(msg, msg), wParam, lParam) # Pass all messages to the original WndProc try: return win32gui.CallWindowProc(self.old_win32_proc, hWnd, msg, wParam, lParam) except Exception, e: log.error("error delegating call: %s", e)
def do_set_icon_from_file(self, filename): if not hasattr(self.tray_widget, "set_icon_theme_path"): self.tray_widget.set_icon(filename) self._has_icon = True return head, icon_name = os.path.split(filename) if head: debug("do_set_icon_from_file(%s) setting icon theme path=%s", filename, head) self.tray_widget.set_icon_theme_path(head) #remove extension (wtf?) dot = icon_name.rfind(".") if dot>0: icon_name = icon_name[:dot] debug("do_set_icon_from_file(%s) setting icon=%s", filename, icon_name) self.tray_widget.set_icon(icon_name) self._has_icon = True
def set_icon_from_data(self, pixels, has_alpha, w, h, rowstride): #use a temporary file (yuk) try: from gtk import gdk except: #no gtk.gdk... no can do return import tempfile try: _, filename = tempfile.mkstemp(suffix="png") debug("set_icon_from_data%s using temporary file %s", ("%s pixels" % len(pixels), has_alpha, w, h, rowstride), filename) tray_icon = gdk.pixbuf_new_from_data(pixels, gdk.COLORSPACE_RGB, has_alpha, 8, w, h, rowstride) tray_icon.save(filename, "png") self.do_set_icon_from_file(filename) finally: os.unlink(filename)
def MyWndProc(self, hWnd, msg, wParam, lParam): assert hWnd == self.getHWND(), "invalid hwnd: %s (expected %s)" % ( hWnd, self.getHWND()) if msg in IGNORE_EVENTS: debug("%s: %s / %s", IGNORE_EVENTS.get(msg), wParam, lParam) elif msg == WM_TRAY_EVENT: self.tray_event(wParam, lParam) elif msg == win32con.WM_ACTIVATEAPP: debug("WM_ACTIVATEAPP focus changed: %s / %s", wParam, lParam) else: log.warn("unexpected message: %s / %s / %s", KNOWN_WM_EVENTS.get(msg, msg), wParam, lParam) # Pass all messages to the original WndProc try: return win32gui.CallWindowProc(self.old_win32_proc, hWnd, msg, wParam, lParam) except Exception, e: log.error("error delegating call: %s", e)
def detect_win32_session_events(self, app_hwnd): """ Use pywin32 to receive session notification events. """ if app_hwnd is None: if self.tray_widget is None: #probably closing down, don't warn return log.warn("detect_win32_session_events(%s) missing handle!", app_hwnd) return try: debug("detect_win32_session_events(%s)", app_hwnd) #register our interest in those events: #http://timgolden.me.uk/python/win32_how_do_i/track-session-events.html#isenslogon #http://stackoverflow.com/questions/365058/detect-windows-logout-in-python #http://msdn.microsoft.com/en-us/library/aa383841.aspx #http://msdn.microsoft.com/en-us/library/aa383828.aspx win32ts.WTSRegisterSessionNotification(app_hwnd, win32ts.NOTIFY_FOR_THIS_SESSION) #catch all events: http://wiki.wxpython.org/HookingTheWndProc self.old_win32_proc = win32gui.SetWindowLong(app_hwnd, win32con.GWL_WNDPROC, self.MyWndProc) except Exception, e: log.error("failed to hook session notifications: %s", e)
def tray_event(self, wParam, lParam): x, y = win32api.GetCursorPos() size = win32api.GetSystemMetrics(win32con.SM_CXSMICON) self.recalculate_geometry(x, y, size, size) if lParam in BALLOON_EVENTS: debug("WM_TRAY_EVENT: %s", BALLOON_EVENTS.get(lParam)) elif lParam == win32con.WM_MOUSEMOVE: debug("WM_TRAY_EVENT: WM_MOUSEMOVE") if self.mouseover_cb: self.mouseover_cb(x, y) elif lParam in BUTTON_MAP: debug("WM_TRAY_EVENT: click %s", BUTTON_MAP.get(lParam)) else: log.warn("WM_TRAY_EVENT: unknown event: %s / %s", wParam, lParam)
def tray_event(self, wParam, lParam): x, y = win32api.GetCursorPos() size = win32api.GetSystemMetrics(win32con.SM_CXSMICON) self.recalculate_geometry(x, y, size, size) if lParam in BALLOON_EVENTS: debug("WM_TRAY_EVENT: %s", BALLOON_EVENTS.get(lParam)) elif lParam==win32con.WM_MOUSEMOVE: debug("WM_TRAY_EVENT: WM_MOUSEMOVE") if self.mouseover_cb: self.mouseover_cb(x, y) elif lParam in BUTTON_MAP: debug("WM_TRAY_EVENT: click %s", BUTTON_MAP.get(lParam)) else: log.warn("WM_TRAY_EVENT: unknown event: %s / %s", wParam, lParam)
def popup_menu(self, widget, button, time, *args): debug("popup_menu(%s, %s, %s, %s)", widget, button, time, args) self.click_cb(button, 1, 0) self.click_cb(button, 0, 0)
def popup_menu(self, widget, button, time, *args): debug("popup_menu(%s, %s, %s, %s)", widget, button, time, args) self.may_guess() self.click_cb(button, 1, 0) self.click_cb(button, 0, 0)
def quit(self, *args): debug("quit(%s) exit_cb=%s", args, self.exit_cb) if self.exit_cb: self.exit_cb() return True #we've handled the quit request ourselves - I hope.. return False
def activate_menu(self, widget, *args): debug("activate_menu(%s, %s)", widget, args) self.click_cb(1, 1) self.click_cb(1, 0)
def activate_menu(self, widget, *args): debug("activate_menu(%s, %s)", widget, args) self.may_guess() self.click_cb(1, 1) self.click_cb(1, 0)