def get_workareas(): try: workareas = [] for m in EnumDisplayMonitors(): mi = GetMonitorInfo(m) screenlog("get_workareas() GetMonitorInfo(%s)=%s", m, mi) #absolute workarea / monitor coordinates: wx1, wy1, wx2, wy2 = mi['Work'] mx1, my1, mx2, my2 = mi['Monitor'] assert mx1 < mx2 and my1 < my2, "invalid monitor coordinates" #clamp to monitor, and make it all relative to monitor: rx1 = max(0, min(mx2 - mx1, wx1 - mx1)) ry1 = max(0, min(my2 - my1, wy1 - my1)) rx2 = max(0, min(mx2 - mx1, wx2 - mx1)) ry2 = max(0, min(my2 - my1, wy2 - my1)) assert rx1 < rx2 and ry1 < ry2, "invalid relative workarea coordinates" geom = rx1, ry1, rx2 - rx1, ry2 - ry1 #GTK will return the PRIMARY monitor first, #so we have to do the same thing: if mi['Flags'] & MONITORINFOF_PRIMARY: workareas.insert(0, geom) else: workareas.append(geom) assert workareas screenlog("get_workareas()=%s", workareas) return workareas except Exception as e: screenlog.warn("failed to query workareas: %s", e) return []
def get_workarea(): #this is for x11 servers which can only use a single workarea, #calculate the total area: try: #first we need to find the absolute top-left and bottom-right corners #so we can make everything relative to 0,0 monitors = [] for m in EnumDisplayMonitors(): mi = GetMonitorInfo(m) mx1, my1, mx2, my2 = mi['Monitor'] monitors.append((mx1, my1, mx2, my2)) minmx = min(x[0] for x in monitors) minmy = min(x[1] for x in monitors) maxmx = max(x[2] for x in monitors) maxmy = max(x[3] for x in monitors) screenlog("get_workarea() absolute total monitor area: %s", (minmx, minmy, maxmx, maxmy)) screenlog(" total monitor dimensions: %s", (maxmx - minmx, maxmy - minmy)) workareas = [] for m in EnumDisplayMonitors(): mi = GetMonitorInfo(m) #absolute workarea / monitor coordinates: wx1, wy1, wx2, wy2 = mi['Work'] workareas.append((wx1, wy1, wx2, wy2)) assert len(workareas) > 0 minwx = min(w[0] for w in workareas) minwy = min(w[1] for w in workareas) maxwx = max(w[2] for w in workareas) maxwy = max(w[3] for w in workareas) #sanity checks: assert minwx >= minmx and minwy >= minmy and maxwx <= maxmx and maxwy <= maxmy, "workspace %s is outside monitor space %s" % ( (minwx, minwy, maxwx, maxwy), (minmx, minmy, maxmx, maxmy)) #now make it relative to the monitor space: wx1 = minwx - minmx wy1 = minwy - minmy wx2 = maxwx - minmx wy2 = maxwy - minmy assert wx1 < wx2 and wy1 < wy2, "invalid workarea coordinates: %s" % ( (wx1, wy1, wx2, wy2), ) return wx1, wy1, wx2 - wx1, wy2 - wy1 except Exception as e: screenlog.warn("failed to query workareas: %s", e) return []
def get_geometry(self): #we can only use this if there is a single monitor #because multi-monitor coordinates may have offsets #we don't know about (done inside GTK) n = len(EnumDisplayMonitors()) if n == 1: nii = NOTIFYICONIDENTIFIER() nii.cbSize = sizeof(NOTIFYICONIDENTIFIER) nii.hWnd = self.hwnd nii.uID = self.app_id #nii.guidItem = XPRA_GUID rect = RECT() if Shell_NotifyIconGetRect(byref(nii), byref(rect)) == 0: geom = (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top) geomlog("Shell_NotifyIconGetRect: %s", geom) return geom return None
def get_monitors(): monitors = [] for m in EnumDisplayMonitors(): mi = GetMonitorInfo(m) monitors.append(mi) return monitors