def find_simulator_window(self): """ Figure out where the simulator opened on screen for video capture """ count = 0 found = False attempts = 10 if 'capture_rect' in self.job: del self.job['capture_rect'] while count < attempts and not found: from Quartz import (CGWindowListCopyWindowInfo, kCGWindowListOptionOnScreenOnly, kCGNullWindowID) windowList = CGWindowListCopyWindowInfo( kCGWindowListOptionOnScreenOnly, kCGNullWindowID) for window in windowList: ownerName = window['kCGWindowOwnerName'] if ownerName == "Simulator": x = int(window['kCGWindowBounds']['X']) y = int(window['kCGWindowBounds']['Y']) width = int(window['kCGWindowBounds']['Width']) height = int(window['kCGWindowBounds']['Height']) # Use the biggest window belonging to Simulator if not found or (width * height) > ( self.job['capture_rect']['width'] * self.job['capture_rect']['height']): self.job['capture_rect'] = { 'x': x, 'y': y, 'width': width, 'height': height } logging.debug("Simulator window: %d,%d - %d x %d", x, y, width, height) found = True if count < attempts and not found: time.sleep(0.5)
def get_xquartz_open_windows(): """ Get info on all open XQuartz windows. Requires pyobjc-framework-Quartz (install with pip) :return: a list of open windows as python dictionaries """ try: from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionAll, kCGNullWindowID from PyObjCTools import Conversion except ImportError: return None # need to use kCGWindowListOptionAll to include windows that are not currently on screen (e.g. minimized) windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID) # then filter for XQuartz main windows open_windows = [ window for window in windows if window['kCGWindowOwnerName'] == "XQuartz" and window['kCGWindowLayer'] == 0 and 'kCGWindowName' in window.keys() and window['kCGWindowName'] not in ['', 'X11 Application Menu', 'X11 Preferences'] ] # convert from NSDictionary to python dictionary open_windows = Conversion.pythonCollectionFromPropertyList(open_windows) return open_windows
def getProcessList(self): options = kCGWindowListOptionAll | kCGWindowListExcludeDesktopElements windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) processList = [] for window in windowList: processList.append(window['kCGWindowOwnerName']) return processList
def active_window_info(): app = NSWorkspace.sharedWorkspace().frontmostApplication() active_app_pid = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationProcessIdentifier'] #active_app_pid = app['NSApplicationProcessIdentifier'] active_app_name = app.localizedName() options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) windowTitle = 'Unknown' for window in windowList: pid = window['kCGWindowOwnerPID'] #windowNumber = window['kCGWindowNumber'] ownerName = window['kCGWindowOwnerName'] geometry = window['kCGWindowBounds'] windowTitle = window.get('kCGWindowName', u'Unknown') if windowTitle and (pid == active_app_pid or ownerName == active_app_name): LOGGER.debug( 'darwin: ownerName=%s, windowName=%s, x=%s, y=%s, ' 'width=%s, height=%s', window['kCGWindowOwnerName'], window.get('kCGWindowName', u'Unknown'), geometry['X'], geometry['Y'], geometry['Width'], geometry['Height']) return { 'app': ownerName, 'geometry': geometry, 'title': windowTitle, 'name': window.get('kCGWindowName', u'Unknown'), }
def snapshot_league_window(): """ Attempts to find an active LoL client window and screenshot it using the appropriate functions given the computer architecture. Expects to be called during the loading screen to a TFT game otherwise the snapshot produced will not work later. Currently expects either Mac OS X or Windows :return: """ is_osx = platform.system() == 'Darwin' if is_osx: window_list = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID) for window in window_list: try: window_name = window['kCGWindowName'] if window_name == MAC_LEAGUE_CLIENT_WINDOW_NAME: filename = generate_filename() os.system('screencapture -l %s %s' % (window['kCGWindowNumber'], filename)) return filename except KeyError: continue print( "Could not find active LoL client -- are you in the loading screen?" ) return ""
def onClickRecordStart(self): command = "pgrep -l %s | awk '{print $1}'" %(self.current_game) child = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True) result = child.communicate()[0].strip() game_started = False options = kCGWindowListOptionOnScreenOnly geometry = None while game_started == False: window_list = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in window_list: pid = window['kCGWindowOwnerPID'] if str(result) == str(pid): geometry = window['kCGWindowBounds'] print geometry game_started = True applescript = os.getcwd()+'/AppleScripts/recorder.scpt' command = 'osascript '+applescript os.system(command) mouse =Controller() time.sleep(1) mouse.position = (geometry['X'], geometry['Y']+(geometry['Height']-self.height)) time.sleep(1) print 'start : ('+str(geometry['X'])+', '+str(geometry['Y']+(geometry['Height']-self.height))+')' mouse.press(Button.left) time.sleep(1) mouse.position = (geometry['X']+geometry['Width'], geometry['Y']+geometry['Height']) print 'start : ('+str(geometry['X']+geometry['Width'])+', '+str( geometry['Y']+geometry['Height'])+')' time.sleep(1) mouse.release(Button.left) time.sleep(1) mouse.position = ((2*geometry['X']+geometry['Width'])/2, (2*geometry['Y']+2*geometry['Height']-self.height)/2) time.sleep(1) mouse.click(Button.left, 1)
def get_browser_bounds(): runningApp = NSWorkspace.sharedWorkspace().frontmostApplication() runningAppPid = runningApp.processIdentifier() windows = CGWindowListCopyWindowInfo( kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID) possibleWindows = [] for wnd in windows: if wnd['kCGWindowOwnerPID'] == runningAppPid: possibleWindows.append(wnd) fallback = False if len(possibleWindows) == 0: # fallback mode fallback = True elif len(possibleWindows) == 1: window = possibleWindows[0] else: fallback = True for wnd in possibleWindows: #if 'netflix' in wnd['kCGWindowName'].lower(): if int(wnd['kCGWindowLayer']) < 0: window = wnd fallback = False break if fallback: # return fallback return dict(Height=NSScreen.mainScreen().frame().size.height, Width=NSScreen.mainScreen().frame().size.width, X=0, Y=0) else: return window['kCGWindowBounds']
def getRootElement(pid=0, name=""): wl = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID) for w in wl: p = int((w.valueForKey_('kCGWindowOwnerPID'))) n = w.valueForKey_('kCGWindowOwnerName') if (pid and p == pid) or (name and n == name): return AXUIElementCreateApplication(p)
def all(cls) -> Iterable[Window]: '''Iterate all windows''' try: # pylint: disable=no-name-in-module,import-outside-toplevel from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionAll, kCGNullWindowID except ModuleNotFoundError: return for window in CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID): yield cls(window)
def grabImage(): windows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID) for window in windows: #print(window) try: if window['kCGWindowName'] == 'Krunker': print('Krunker window found!') print(window) # get window dimensions x = int(window['kCGWindowBounds']['X']) y = int(window['kCGWindowBounds']['Y']) width = int(window['kCGWindowBounds']['Width']) height = int(window['kCGWindowBounds']['Height']) print('Dimensions: {}'.format((x, y, width, height))) center = (width // 2, height // 2) print('Center: {}'.format(center)) window_id = int(window['kCGWindowNumber']) print('Window ID: {}'.format(window_id)) #region = CGRectMake(x, y, width, height) #region = CGRectInfinite # get img data img = CGWindowListCreateImage(CGRectInfinite, kCGWindowListOptionAll, window_id, kCGWindowImageDefault) prov = CGImageGetDataProvider(img) img_data = CGDataProviderCopyData(prov) img_width, img_height = CGImageGetWidth(img), CGImageGetHeight( img) # create canvas based on image data pixels canvas = PNGCanvas(img_width, img_height) for x in range(img_width): for y in range(img_height): offset = 4 * ( (img_width * int(round(y))) + int(round(x))) b, g, r, a = struct.unpack_from('BBBB', img_data, offset=offset) canvas.point(x, y, color=(r, g, b, a)) # dump canvas to png with open('test.png', 'wb') as f: f.write(canvas.dump()) except: # handle exception pass
def _is_main_window_open(self): """Main window, not login one""" windows = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID) for window in windows: try: if 'Blizzard Battle.net' == window['kCGWindowName']: log.debug('Main Battle.net window was found') return True except KeyError: continue return False
def get_current_window_name(self): options = kCGWindowListOptionOnScreenOnly window_list = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in window_list: try: if window['kCGWindowOwnerName'] == self.current_app: window_name = window['kCGWindowName'] return window_name except KeyError: pass return None
def fetch_window_title(self) -> str: active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication( ).localizedName() options = kCGWindowListOptionOnScreenOnly window_list = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in window_list: if window["kCGWindowOwnerName"] == active_app_name: return window.get("kCGWindowName", "Unknown") else: return "Unknown"
def get_win_pos(): win_name = [] options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in windowList: ownerName = window['kCGWindowOwnerName'] geometry = window['kCGWindowBounds'] win_name.append(ownerName) if ownerName == "Hyperion": return geometry["X"], geometry["Y"] if "Hyperion" not in win_name: return 9999, 9999
def getWindows(self): ''' Return a list of tuples (win_id, win_title) for each real window. ''' window_list = CGWindowListCopyWindowInfo( kCGWindowListExcludeDesktopElements | kCGWindowListOptionOnScreenOnly, kCGNullWindowID) return [(win.valueForKey_('kCGWindowNumber'), win.valueForKey_('kCGWindowName')) for win in window_list if win.valueForKey_('kCGWindowSharingState') and win.valueForKey_('kCGWindowName')]
def get_pid_by_name(name): pids = [] for window in CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID): pid = window['kCGWindowOwnerPID'] ownerName = window['kCGWindowOwnerName'] windowNumber = window['kCGWindowNumber'] windowTitle = window.get('kCGWindowName', u'Unknown') geometry = window['kCGWindowBounds'] if name in ownerName or name in windowTitle: pids.append(pid) pids = list(set(pids)) return pids
def update_zoom_window_info(self): window_list = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID) for i in range(len(window_list)): window = window_list[i] try: if ZOOM in window['kCGWindowName']: self.zoom_window_info = (i, window['kCGWindowBounds']) break except: pass else: # if we reach the end of the loop, no Zoom window raise Exception("Could not find Zoom window.")
def applicationDidFinishLaunching_(self, notification): workspace = NSWorkspace.sharedWorkspace() activeApps = workspace.runningApplications() for app in activeApps: if app.isActive(): options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo( options, kCGNullWindowID) for window in windowList: if window['kCGWindowOwnerName'] == app.localizedName(): NSLog('%@', window) break break AppHelper.stopEventLoop()
def getActiveInfo(): app = NSWorkspace.sharedWorkspace().frontmostApplication() active_app_name = app.localizedName() options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) windowTitle = 'Unknown' for window in windowList: windowNumber = window['kCGWindowNumber'] ownerName = window['kCGWindowOwnerName'] geometry = window['kCGWindowBounds'] windowTitle = window.get('kCGWindowName', u'Unknown') if windowTitle and ownerName == active_app_name: return windowNumber, ownerName, geometry, windowTitle return None
def GetActiveWindow_macOS(self): curr_app = NSWorkspace.sharedWorkspace().frontmostApplication() curr_pid = NSWorkspace.sharedWorkspace().activeApplication( )['NSApplicationProcessIdentifier'] curr_app_name = curr_app.localizedName() options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in windowList: pid = window['kCGWindowOwnerPID'] windowNumber = window['kCGWindowNumber'] ownerName = window['kCGWindowOwnerName'] geometry = window['kCGWindowBounds'] windowTitle = window.get('kCGWindowName', u'Unknown') if curr_pid == pid: return windowTitle
def get_xquartz_open_windows(): """ Get info on all open XQuartz windows. Requires pyobjc-framework-Quartz (install with pip) :return: a list of open windows as python dictionaries """ # pyobjc-framework-Quartz can segfault if the wrong version is installed logger = logging.getLogger(__name__) p = subprocess.Popen([sys.executable, "-c", "import Quartz"]) p.communicate() if p.returncode == -signal.SIGSEGV: logger.warning( "Import of pyobjc-framework-Quartz failed due to a segmentation fault. " "The installed version is incompatible with your system.") return None try: from Quartz import ( CGWindowListCopyWindowInfo, kCGWindowListExcludeDesktopElements, kCGNullWindowID, ) from PyObjCTools import Conversion except ImportError: # pragma: no cover logger.warning( "Import of pyobjc-framework-Quartz failed. Try installing with pip." ) return None # need to use kCGWindowListExcludeDesktopElements to include windows # that are not currently on screen (e.g. minimized). # kCGWindowListExcludeDesktopElements | kCGWindowListOptionOnScreenOnly # will exclude minimized windows. Use KEEP_XQUARTZ if this is an issue. windows = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID) # then filter for XQuartz main windows open_windows = [ window for window in windows if window["kCGWindowOwnerName"] == "XQuartz" and window["kCGWindowLayer"] == 0 and window["kCGWindowBounds"]["X"] != 0 and window["kCGWindowBounds"]["Y"] != 0 ] # convert from NSDictionary to python dictionary open_windows = Conversion.pythonCollectionFromPropertyList(open_windows) return open_windows
def get_windows_titles(): try: if platform.system() == 'Darwin': ws_options = kCGWindowListOptionOnScreenOnly windows_list = CGWindowListCopyWindowInfo(ws_options, kCGNullWindowID) maya_titles = { x.get('kCGWindowName', u'Unknown') for x in windows_list if 'Maya' in x['kCGWindowOwnerName'] } # duct tape for windows with empty title expected = {'Maya', 'Render View', 'Rendering...'} if maya_titles - expected: maya_titles.add('Detected windows ERROR') return list(maya_titles) elif platform.system() == 'Windows': EnumWindows = ctypes.windll.user32.EnumWindows EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)) GetWindowText = ctypes.windll.user32.GetWindowTextW GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW IsWindowVisible = ctypes.windll.user32.IsWindowVisible titles = [] def foreach_window(hwnd, lParam): if IsWindowVisible(hwnd): length = GetWindowTextLength(hwnd) buff = ctypes.create_unicode_buffer(length + 1) GetWindowText(hwnd, buff, length + 1) titles.append(buff.value) return True EnumWindows(EnumWindowsProc(foreach_window), 0) return titles except Exception as err: core_config.main_logger.error( 'Exception has occurred while pull windows titles: {}'.format( str(err))) return []
def get_window_name(self, pid): '''Get a window name by PID. This method employs functionality of Quartz Window Server in order to get a name of the window. Documentation: https://developer.apple.com/documentation/coregraphics/quartz_window_services ''' # List of currently opened windows l = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID) for window in l: if window['kCGWindowOwnerPID'] == pid: return window['kCGWindowName'] return ''
def get_title(pid): # Processes title of application from PID logging.debug("Getting title for the application...") curr_app = NSWorkspace.sharedWorkspace().frontmostApplication() curr_pid = NSWorkspace.sharedWorkspace().activeApplication( )['NSApplicationProcessIdentifier'] curr_app_name = curr_app.localizedName() options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in windowList: pid = window['kCGWindowOwnerPID'] windowNumber = window['kCGWindowNumber'] ownerName = window['kCGWindowOwnerName'] geometry = window['kCGWindowBounds'] windowTitle = window.get('kCGWindowName', u'Unknown') if curr_pid == pid: logging.debug("Title of application: " + windowTitle.encode('ascii', 'ignore')) return windowTitle
def getInfoWindowsDarwin(self): # on cherche sur les anciennes version de spotify le titre Spotify options = kCGWindowListOptionAll windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) #result = osascript.run("""set appName to "Spotify" \n if application appName is running then \n tell application "Spotify" \n set c to current track \n return {(artist of c), (album of c)} \n end tell \n else \n return "not running" \n end if""") for window in windowList: if window["kCGWindowOwnerName"] == "Spotify": (error_code, current_track, other) = osascript.run( """tell application "Spotify" \n set c to current track \n return {(artist of c), (album of c)} \n end tell""" ) if current_track == ",": return ("Error", "Nothing playing") else: try: artist, track = current_track.split(",", 1) return (artist.strip(), track.strip()) except Exception as e: return ("Error", "Nothing playing")
def get_active_window(): try: if sys.platform == "darwin": app = NSWorkspace.sharedWorkspace().frontmostApplication() active_app_name = app.localizedName() options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) windowTitle = 'Unknown' for window in windowList: windowNumber = window['kCGWindowNumber'] ownerName = window['kCGWindowOwnerName'] # geometry = window['kCGWindowBounds'] windowTitle = window.get('kCGWindowName', u'Unknown') if windowTitle and (event_window_num == windowNumber or ownerName == active_app_name): # log.debug( # 'ownerName=%s, windowName=%s, x=%s, y=%s, ' # 'width=%s, height=%s' # % (window['kCGWindowOwnerName'], # window.get('kCGWindowName', u'Unknown'), # geometry['X'], # geometry['Y'], # geometry['Width'], # geometry['Height'])) break return _review_active_info(active_app_name, windowTitle) if sys.platform == "win32": pid = win32process.GetWindowThreadProcessId( win32gui.GetForegroundWindow() ) # This produces a list of PIDs active window relates to program_name = psutil.Process(pid[-1]).name() print(psutil.Process(pid[-1]).name() ) # pid[-1] is the most likely to survive last longer active_window = GetWindowText(GetForegroundWindow()) return program_name, active_window except: log.error('Unexpected error: %s' % sys.exc_info()[0]) log.error('error line number: %s' % sys.exc_traceback.tb_lineno) return 'Unknown', 'Unknown'
def get_tables(): tables = [] # kCGWindowListOptionOnScreenOnly should ensure that windows # are displayed in order, i.e. tables[0] will be the front-most # table. windows = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID) for window in windows: # this is redundant, we can merge these lists and simplify the # check below. blocked_windows = ['PokerStars Lobby', 'PokerStars', 'Focus Proxy'] blocked_tables = ['Spin', 'Lobby', 'Rematch', 'Auto Rebuy', 'Buy-in'] # check for key before trying to access it if 'kCGWindowName' in window: conditions = [window['kCGWindowOwnerName'] in POKER_CLIENTS, window['kCGWindowName'] not in blocked_windows, not any([t in window['kCGWindowName'] for t in blocked_tables])] if all(conditions): tables.append(window) return tables
def find_window(self): activeApps = self.workspace.runningApplications() #Have to look into this if it is too slow on move and scroll, #right now the check is done for everything. for app in activeApps: if app.isActive(): options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo( options, kCGNullWindowID) for window in windowList: if window['kCGWindowOwnerName'] == app.localizedName(): geometry = window['kCGWindowBounds'] window_name = self.get_window_name(window) self.screen_hook(window['kCGWindowOwnerName'], window_name, geometry['X'], geometry['Y'], geometry['Width'], geometry['Height']) break break
def receiveWorkspaceChangeNotification_(self, aNotification): workspacelog("receiveWorkspaceChangeNotification_(%s)", aNotification) if not CGWindowListCopyWindowInfo: return try: ourpid = os.getpid() windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionAll | kCGWindowListOptionOnScreenOnly, kCGNullWindowID) our_windows = {} for window in windowList: pid = window['kCGWindowOwnerPID'] if pid==ourpid: num = window['kCGWindowNumber'] name = window['kCGWindowName'] our_windows[num] = name workspacelog("workspace change - our windows on screen: %s", our_windows) if our_windows: self.delegate_cb("wake_callback") else: self.delegate_cb("sleep_callback") except: workspacelog.error("Error querying workspace info", exc_info=True)
def find_window_geometry_by_name(appName): workspace = NSWorkspace.sharedWorkspace() runningApps = workspace.runningApplications() for app in runningApps: #if app.isActive(): if app.localizedName() == appName: #print ('one more', app.localizedName()) options = kCGWindowListOptionOnScreenOnly windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) for window in windowList: if window['kCGWindowOwnerName'] == app.localizedName(): #print(window.getKeys_) kCGWindowBounds = window['kCGWindowBounds'] #print(kCGWindowBounds) # height = kCGWindowBounds['Height'] # width = kCGWindowBounds['Width'] # X = kCGWindowBounds['X'] # Y = kCGWindowBounds['Y'] return kCGWindowBounds #(X, Y, height, width) break break