def app_windows_image(): ''' Returns a bitmap showing all the top level windows in this application. Other areas of the screen are blanked out. ''' # get the union of all screen rectangles (this will be a big rectangle # covering the area of all monitors) rect = reduce(wx.Rect.Union, (m.Geometry for m in Monitor.All())) if "wxMSW" in wx.PlatformInfo: screen = getScreenBitmap(rect).PIL else: screen = wx.ScreenDC().GetAsBitmap().PIL mask = Image.new('RGBA', rect.Size, (255, 255, 255, 255)) drawrect = lambda r: ImageDraw.Draw(mask).rectangle( [r.x, r.y, r.Right, r.Bottom], fill=(0, 0, 0, 0)) # draw rectangles into a mask for each top level window (and the system tray) for r in [GetTrayRect() ] + [w.Rect for w in wx.GetTopLevelWindows() if w.IsShown()]: r.Offset((-rect.Position[0], -rect.Position[1] )) # some monitors may be in negative coordinate space... drawrect(r) # paste the mask into the screenshot--whiteing out areas not in our windows screen_full = screen.copy() screen.paste(mask, (0, 0), mask) return screen_full, screen
def check(self): ''' get number of displays associate current windows with displays destroy other windows, clear state create new if necessary ''' current = set( (n, tuple(m.Geometry)) for n, m in enumerate(Monitor.All())) last_time = set(self.frames.keys()) new = current - last_time dead = last_time - current check = last_time & current for n, geo in dead: f = self.frames.pop((n, geo)) f.Destroy() self.values.pop((n, geo)) for n, geo in new: self.frames[(n, geo)] = self.new_win(n, geo) self.values[(n, geo)] = False for n, geo in check: self.fix_win(n, geo)
def OnShow(self,event): event.Skip() if not self.win.Shown: return onRight = self.side == ABE_RIGHT mon = Monitor.GetFromWindow(self.win) #@UndefinedVariable monRect = mon.ClientArea atEdge = not onscreen(monRect.Right+1 if onRight else monRect.Left-1, monRect.Y) shouldDock = self.wasDocked or (self.firstShow and (atEdge or not self.AutoHide)) if self.Enabled and shouldDock and self.side is not None and not self.docked: self.Dock(setFrameStyle = self.firstShow) self.firstShow = False self.bypassMoveEvents = True self.win.SetRect(self.dockedRect) self.bypassMoveEvents = False self.docking = True self.docked = False self.OnExitSizeMove() elif self.firstShow: self.firstShow = False self.wasDocked = False
def OnDisplayChanged(self, event): log.debug('OnDisplayChanged') if self.docked and not self.AutoHide: self.Undock(setFrameStyle=False) self.win.FitInScreen(Monitor.GetFromDeviceId(self.monId)) #@UndefinedVariable self.Dock(setFrameStyle=False) self.bypassMoveEvents = True self.win.SetRect(self.dockedRect) self.bypassMoveEvents = False self.docking = True self.docked = False self.OnExitSizeMove() elif self.docked and self.AutoHide: onRight = self.side == ABE_RIGHT mon = Monitor.GetFromDeviceId(self.monId) #@UndefinedVariable monRect = mon.ClientArea xPos = monRect.Right+1 if onRight else monRect.Left-1 while onscreen(xPos, monRect.Y): mon = Monitor.GetFromPoint((xPos, monRect.Y)) #@UndefinedVariable monRect = mon.ClientArea xPos = monRect.Right+1 if onRight else monRect.Left-1 # self.win.FitInScreen(mon) if onRight: self.dockedRect = wx.Rect(monRect.Right-self.win.Size.width + 1, monRect.Top, self.win.Size.width, monRect.Bottom - monRect.Top) else: self.dockedRect = wx.Rect(monRect.left-1,monRect.Top, self.win.Size.width, monRect.Bottom - monRect.Top) self.bypassMoveEvents = True self.win.SetRect(self.dockedRect) self.bypassMoveEvents = False self.GoAway(monRect) event.Skip()
def Reposition(self, rect): self._customMenu.CalcSize() menuSize = self._customMenu.GetMinSize() pos = wx.Point(rect.GetLeft(), rect.GetBottom() + 1) from gui.toolbox import Monitor monRect = Monitor.GetFromPoint(pos, True).Geometry if pos.y + menuSize.height > monRect.bottom: pos = wx.Point(rect.GetLeft(), rect.GetTop() - menuSize.height - 1) return pos
def infobox(): from gui.toolbox import Monitor from gui.infobox.infobox import DEFAULT_INFOBOX_WIDTH from gui.infobox.infoboxapp import init_host, set_hosted_content f = wx.Frame(None) size = (DEFAULT_INFOBOX_WIDTH, Monitor.GetFromWindow(f).ClientArea.height * .75) f.SetClientSize(size) w = wx.webview.WebView(f) init_host(w) set_hosted_content(w, MockTwitterAccount(twitter)) f.Show()
def get_infobox_tray_position(self): #TODO: find taskbar position from the correct HWND. this code assumes the mouse # is on the same display as the tray, and that the tray is on the bottom of the # "client area" rectangle returned by wxDisplay try: import cgui r = cgui.GetTrayRect() pt = Point(r.Right - r.Width / 2, r.Bottom - r.Height / 2) display = Monitor.GetFromPoint(pt, find_near=True) rect = display.GetClientArea() distances = [] for p in ('TopLeft', 'TopRight', 'BottomLeft', 'BottomRight'): corner = getattr(rect, p) distances.append((corner, corner.DistanceTo(pt), p)) distances.sort(key=itemgetter(1)) corner, distance, name = distances[0] return corner except Exception: print_exc() return Monitor.GetFromPointer().ClientArea.BottomRight
def Display(self,rect): 'Set Position and popup' pos = rect.BottomLeft newrect = wx.RectPS(pos, self.Size) screenrect = Monitor.GetFromRect(newrect).ClientArea if newrect.bottom > screenrect.bottom: pos.y -= rect.height + self.Size.height if newrect.right > screenrect.right: pos.x += rect.width - self.Size.width self.SetPosition(pos) # Position property doesn't work for PopTransWin self.Popup()
def Dock(self, side = None, setFrameStyle = True): """ Dock to the side of the screen storing un-docked information for later use If self.AutoHide is True tries docking with autohide first, attempting to dock regularly if that fails or if self.autohide is False Sets the following: self.side self.oldSize self.autohidden - Only in autohide mode Calls self.OnDock in either docking style returns True if either docking style succeeds, None otherwise """ log.debug('Dock') self.monId = Monitor.GetFromWindow(self.win).DeviceId #@UndefinedVariable if side is not None: self.side = side if self.AutoHide: if SHAppBarMessage(ABM_SETAUTOHIDEBAR, self.GetNewAppBarData(True)): log.info('registered autohide %s', sideStrings[self.side]) if setFrameStyle: SetToolStyle(self.win, True) self.SetWinAlwaysOnTop(True) if self.oldSize is None: self.oldSize = self.win.Size self.SetAutoHidePos() self.timer.Start(AUTOHIDE_TIMER_MS) self.autohidden = False self.OnDock(True) return True else: log.warning('obtaining autohide bar failed') # fall back to normal docking if SHAppBarMessage(ABM_NEW, self.newAppBarData): self.oldSize = self.oldSize or self.win.Size if setFrameStyle: SetToolStyle(self.win, True) # self.SetWinAlwaysOnTop(True) self.AppBarQuerySetPos(set = False) self.OnDock(True) return True
def on_maximize(self, e): self.inMaximize = True monitor = Monitor.GetFromWindow(self) assert monitor if self.userSizeForMaximize: self.SetSize(self.userSizeForMaximize) self.userSizeForMaximize = None return else: self.userSizeForMaximize = self.Size display_size = monitor.GetClientArea() max_size_needed = self.buddyListPanel.GetMaxRequiredSize() max_size_needed.y += 22 # add the title bar height to the total size final_size = max_size_needed if max_size_needed.x > display_size.width: final_size.x = display_size.width if max_size_needed.y > display_size.height: final_size.y = display_size.height # if our y position + height go below the bottom of the display, # move the y position up to help fit it pos = self.GetPosition() if pos.y + final_size.y > display_size.height - pos.y: extra_y = abs(display_size.height - pos.y - final_size.y) pos.y -= extra_y self.SetPosition(pos) print "display_size = %r" % display_size print "final_size = %r, max_size_needed = %r" % (final_size, max_size_needed) self.SetSize(final_size) self.inMaximize = False
def Display(self, caller=None, funnle=True, funnlefullscreen=False): """ Display the menu """ self.BeforeDisplay() if not self.IsShown() and len(self): self.spine.CalcSize() if caller and isinstance(caller, SimpleMenuSpine): self.caller = None rect = caller.GetSelectionRect() position = Point(rect.x + rect.width, rect.y - self.spine.framesize.top) newrect = RectPS(position, self.ScreenRect.Size) screenrect = Monitor.GetFromRect(newrect).Geometry if newrect.bottom > screenrect.bottom: position.y = rect.y + rect.height - self.Size.height if newrect.right > screenrect.right: position.x = rect.x - self.Size.width elif caller: self.caller = caller caller_rect = caller.ScreenRect position = caller_rect.BottomLeft newrect = RectPS(position, self.ScreenRect.Size) screenrect = Monitor.GetFromWindow(caller).Geometry if newrect.bottom > screenrect.bottom: position.y -= caller_rect.Height + self.spine.Size.height if newrect.right > screenrect.right: position.x += caller_rect.Width - self.spine.Size.width else: self.caller = None position = wx.GetMousePosition() newrect = RectPS(position, self.ScreenRect.Size) screenrect = Monitor.GetFromPoint(position).Geometry if newrect.bottom > screenrect.bottom: position.y -= self.spine.Size.height if newrect.right > screenrect.right and pref( 'menus.shift_mode', False): position.x -= self.spine.Size.width newrect = wx.RectPS(position, self.Size) screenrect = Monitor.GetFromRect(newrect).Geometry pos = screenrect.Clamp(newrect).Position if funnle else position self.SetRect(RectPS(pos, self.Size)) self.spine.SetSelection(-1) fadein(self, 'xfast') self.spine.RefreshAll() if not self.spine.HasCapture(): self.spine.CaptureMouse() wx.CallLater(10, self.Refresh) if not isinstance(caller, SimpleMenuSpine): self.TopConnect()
def isRectOnScreen(rect): return Monitor.GetFromRect(rect, find_near = False) is not None #@UndefinedVariable
def onscreen(x, y): 'Returns True if the specified (x, y) point is on any screen.' return Monitor.GetFromPoint((x, y), find_near = False) is not None #@UndefinedVariable
def monitor_rect(win): 'returns a wxRect for the client area of the monitor the mouse pointer is over' return Monitor.GetFromWindow(win).ClientArea #@UndefinedVariable
def PopupMenu(self, pos=None, submenu=False): v = self.vlist v.menu.Handler._menu_open(menu=v.menu) # fit to the menu size v.SetSelection(-1) v.CalcSize() self.Fit() self.Sizer.Layout() if isinstance(self.bg, SplitImage4): self.Cut(self.bg.GetBitmap(self.Size)) else: self.Cut() pos = RectPS(self._guess_position(), wx.Size( 0, 0)) if pos is None else pos try: try: disp = Monitor.GetFromPoint(pos[:2]).Geometry except Exception: disp = Monitor.GetFromPoint(pos.BottomRight, find_near=True).Geometry except Exception: print_exc() log.critical('could not find display for %s, falling back to zero', pos) disp = Monitor.All()[0].Geometry size = self.Size rects = [] add = lambda *seq: rects.extend([RectPS(p, size) for p in seq]) singlepoint = len(pos) == 2 # turn a point into a rectangle of size (0, 0) offset = 2 if singlepoint else 0 if singlepoint: pos = wx.RectPS(pos, (0, 0)) w, h, wh = Point(size.width - offset, 0), Point( 0, size.height - offset), Point(size.width - offset, size.height - offset) difftop = Point(0, self.framesize.top) diffbottom = Point(0, self.framesize.bottom) if submenu: add(pos.TopRight - difftop, pos.TopLeft - w - difftop, pos.BottomRight - h + diffbottom, pos.BottomLeft - wh + diffbottom) else: add(pos.BottomLeft, pos.TopLeft - h, pos.BottomRight - w, pos.TopRight - h, pos.TopRight - wh, pos.BottomLeft - h) for rect in rects: if disp.ContainsRect(rect): self._showat(rect) return rect = rects[0] if hasattr(v.menu, '_button'): # todo: clean up this. brect = v.menu._button.ScreenRect if rect.Intersects(brect): rect.Offset((brect.Width, 0)) self._showat(rect)
def panel(panel, sizer, newgroup, exithooks): display_choices = [(n, str(n + 1)) for n in xrange(Monitor.GetCount())] dddict = { '{location_dropdown}': ('notifications.popups.location', popupchoices), '{monitor_dropdown}': ('notifications.popups.monitor', display_choices) } popup_panel = wx.Panel(panel) popup_sizer = popup_panel.Sizer = HSizer() popupposstr = _( 'Enable &pop-up notifications in the {location_dropdown} on monitor {monitor_dropdown}' ) pattern = re.compile('(.*?)(\{\w*\})(.*?)(\{\w*\})(.*)') m = pattern.search(popupposstr) startstr = m.group(1) dd1 = m.group(2) middlestr = m.group(3) dd2 = m.group(4) endstr = m.group(5) popup_sizer.Add( CheckChoice('notifications.enable_popup', dddict[dd1][0], startstr, dddict[dd1][1])(popup_panel), 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) choice2 = Choice(dddict[dd2][0], dddict[dd2][1], caption=middlestr)(popup_panel) choice2.Enable(get_pref('notifications.enable_popup')) profile.prefs.add_observer( lambda *a: choice2.Enable(get_pref('notifications.enable_popup')), 'notifications.enable_popup', obj=panel) popup_sizer.Add(choice2, 0, wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) if endstr: popup_sizer.Add(Label(endstr)(popup_panel), 0, 3) top = PrefPanel(panel, PrefCollection(popup_panel, Check('enable_sound', _('Enable &sounds'))), _('Notifications'), prefix='notifications') notifications_view = build_notification_area(panel) notifications_view.SetFocus() bottom = PrefPanel(panel, notifications_view, _('Events')) restore_default_button = Button( panel, _('Restore Defaults'), lambda: restore_default_notifications(notifications_view)) if platformName == 'mac': restore_default_button.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) sizer.AddMany([ (top, 0, wx.EXPAND | wx.ALL, 3), (bottom, 1, wx.EXPAND | wx.ALL, 3), (restore_default_button, 0, wx.BOTTOM | wx.LEFT, 4 if platformName == 'mac' else 0), ]) return panel
def screenArea(monitor_n): display_n = min(Monitor.GetCount() - 1, monitor_n) return Monitor.All()[display_n].GetClientArea()
def monitor_rect(win=None): 'returns a wxRect for the client area of the monitor the mouse pointer is over' return (Monitor.GetFromPoint(wx.GetMousePosition()) if win is None else Monitor.GetFromWindow(win)).ClientArea