def gaze_scroll(): # print("gaze_scroll") if (eye_zoom_mouse.zoom_mouse.state == eye_zoom_mouse.STATE_IDLE ): # or eye_zoom_mouse.zoom_mouse.state == eye_zoom_mouse.STATE_SLEEP: x, y = ctrl.mouse_pos() # the rect for the window containing the mouse rect = None # on windows, check the active_window first since ui.windows() is not z-ordered if app.platform == "windows" and ui.active_window().rect.contains( x, y): rect = ui.active_window().rect else: windows = ui.windows() for w in windows: if w.rect.contains(x, y): rect = w.rect break if rect is None: # print("no window found!") return midpoint = rect.y + rect.height / 2 amount = int(((y - midpoint) / (rect.height / 10))**3) actions.mouse_scroll(by_lines=False, y=amount)
def ui_event(event, arg): if amethyst_running(): if event in ( "app_activate", "app_launch", "app_close", "win_open", "win_close", ): if event[:4] == "win_" and arg.app.name in ("Amethyst", "loginwindow"): return if event[:4] == "app_" and arg.name in ( "AddressBookSourceSync", "Google Software Update", "CoreServicesUIAgent", "AddressBookManager", "loginwindow", ): return try: print(event, arg) print(arg.app.name, arg.name) print(ui.active_window()) print(ui.active_window().hidden) print() except: pass press("alt-shift-z") cron.after("250ms", lambda: press("alt-shift-z")) cron.after("250ms", lambda: press("alt-shift-z"))
def new_tab(m): print("hidden", ui.active_window().hidden) print(ui.active_window().children) if not ui.active_window().hidden: press("cmd-t") else: press("cmd-n")
def language(): title = ui.active_window().title #print(str(ui.active_app())) #workaround for VS Code on Mac. The title is "", #but the doc is correct. we will assume the last split #has the extension. this may need to be implemented per-app #this is necesary for things in e.g. .talon if title == "": title = ui.active_window().doc # vim in iTerm has title like: # file-name.ext (/path/to/file-name.ext) - VIM # just grab the first split. if title.endswith("- VIM"): title = title.split(os.path.sep)[0] else: title = title.split(os.path.sep)[-1] m = regex_ext.search(title) if m: extension = m.group(1) if extension in extension_lang_map: return extension_lang_map[extension] else: return extension return ""
def file_manager_current_path(): global path_detection_disabled if path_detection_disabled: logging.warning( 'Skipping WSL path detection - try "weasel reset path detection"' ) return "" path = ui.active_window().title try: path = path.split(":")[1].lstrip() except: path = "" # print("current: " + path) if "~" in path: # the only way I could find to correctly support the user folder: # get absolute path of ~, and strip /mnt/x from the string abs_usr_path = get_usr_path() abs_usr_path = abs_usr_path[abs_usr_path.find("/home" ):len(abs_usr_path)] path = path.replace("~", abs_usr_path) path = get_win_path(path) if path in directories_to_remap: path = directories_to_remap[path] if path in directories_to_exclude: path = "" return path
def language(): title = ui.active_window().title # print(str(ui.active_app())) # workaround for VS Code on Mac. The title is "", # but the doc is correct. if title == "": title = ui.active_window().doc m = regex_ext.search(title) if m: extension = m.group(1) if extension in extension_lang_map: return extension_lang_map[extension] else: return extension return ""
def move_focus_indicator(self, window): cron.cancel(self.move_indicator_job) active_window = ui.active_window() if active_window.rect.x != self.previous_window_x and active_window.rect.y != self.previous_window_y: self.move_indicator_job = cron.after("30ms", self.update_focus_indicator)
def update_focus_indicator(self, window=None): if not window or window.rect.width * window.rect.height > 0 and self.enabled: active_window = ui.active_window() if active_window: app = ui.active_app() theme = actions.user.hud_get_theme() focus_colour = theme.get_colour("focus_indicator_background", "DD4500") focus_text_colour = theme.get_colour( "focus_indicator_text_colour", "FFFFFF") self.previous_window_x = active_window.rect.x self.previous_window_y = active_window.rect.y regions = [ self.content.create_screen_region( "focus", focus_colour, "", "<*" + app.name, -1, active_window.rect.x, active_window.rect.y, active_window.rect.width, active_window.rect.height) ] regions[0].text_colour = focus_text_colour regions[0].vertical_centered = False self.content.publish_event("screen_regions", "focus", "replace", regions) status_icon = self.content.create_status_icon( "focus_toggle", "focus", None, app.name, lambda _, _2: actions.user.hud_deactivate_poller("focus")) self.content.publish_event("status_icons", status_icon.topic, "replace", status_icon)
def internal(m): win = ui.active_window() rect = win.rect center_x = rect.x + rect.width / 2 center_y = rect.y + rect.height / 2 region = regions[m._words[1]] if region == "west": pos = (center_x - multiplier * rect.width / 4, center_y) elif region == "east": pos = (center_x + multiplier * rect.width / 4, center_y) elif region == "north": pos = (center_x, center_y - multiplier * rect.height / 4) elif region == "south": pos = (center_x, center_y + multiplier * rect.height / 4) elif region == "northeast": pos = ( center_x + multiplier * rect.width / 4, center_y - multiplier * rect.height / 4, ) elif region == "northwest": pos = ( center_x - multiplier * rect.width / 4, center_y - multiplier * rect.height / 4, ) elif region == "southeast": pos = ( center_x + multiplier * rect.width / 4, center_y + multiplier * rect.height / 4, ) elif region == "southwest": pos = ( center_x - multiplier * rect.width / 4, center_y + multiplier * rect.height / 4, ) ctrl.mouse_move(*pos)
def mouse_position(m) -> (int, int): typ = m[-1] scr = ui.active_window().screen.rect res = (0, 0) if typ == 'corner': pos = m.corner if pos == 'upper left': res = (scr.x, scr.y) elif pos == 'upper right': res = (scr.x + scr.width, scr.y) elif pos == 'lower left': res = (scr.x, scr.y + scr.height) elif pos == 'lower right': res = (scr.x + scr.width, scr.y + scr.height) elif typ == 'edge': pos = m.edge if pos == "top": res = (scr.x + scr.width / 2, scr.y) elif pos == "right": res = (scr.x + scr.width, scr.y + scr.height / 2) elif pos == "bottom": res = (scr.x + scr.width / 2, scr.y + scr.height) elif pos == "left": res = (scr.x, scr.y + scr.height / 2) elif typ == 'bar': pos = m.edge BAR_MID = 10 if pos == "top": res = (scr.x + scr.width / 2, scr.y + BAR_MID) elif pos == "right": res = (scr.x + scr.width - BAR_MID, scr.y + scr.height / 2) elif pos == "bottom": res = (scr.x + scr.width / 2, scr.y + scr.height - BAR_MID) elif pos == "left": res = (scr.x + BAR_MID, scr.y + scr.height / 2) elif typ == 'area': pos = m.area if pos == 'upper left': res = (scr.x + scr.width * 1 / 4, scr.y + scr.height * 1 / 4) elif pos == 'upper center': res = (scr.x + scr.width * 2 / 4, scr.y + scr.height * 1 / 4) elif pos == 'upper right': res = (scr.x + scr.width * 3 / 4, scr.y + scr.height * 1 / 4) elif pos == 'mid left': res = (scr.x + scr.width * 1 / 4, scr.y + scr.height * 2 / 4) elif pos == 'center': res = (scr.x + scr.width * 2 / 4, scr.y + scr.height * 2 / 4) elif pos == 'mid right': res = (scr.x + scr.width * 3 / 4, scr.y + scr.height * 2 / 4) elif pos == 'lower left': res = (scr.x + scr.width * 1 / 4, scr.y + scr.height * 3 / 4) elif pos == 'lower center': res = (scr.x + scr.width * 2 / 4, scr.y + scr.height * 3 / 4) elif pos == 'lower right': res = (scr.x + scr.width * 3 / 4, scr.y + scr.height * 3 / 4) else: print( f"warning: capture matched a sequence of unknown position type; have you modified the capture rule?" ) return res
def scope(): win = ui.active_window() print(win.title) #results = re.search ('^Emacs; Path=(.*)', win.title) #results = re.search ('^Emacs', win.title) #attrs = vars(ctx) #print(', '.join("%s: %s" % item for item in attrs.items())) #print(attrs.keys()) vnc_app = "Unknown" emacs_path = "" emacs_modes = "" if re.match(r'^Emacs', win.title) is not None: vnc_app = "emacs" results = re.search(r'Path=(.*)\;\sModes=\[?\((.*)\)\]?', win.title) print(str(results)) if results is not None: emacs_path = str(results.group(1)) emacs_modes = str(results.group(2)) else: if re.match(r'Exceed', win.title) is not None: vnc_app = "emacs" #print(etx_app) print(emacs_modes) print(emacs_path) return_dict = {} #return_dict['vnc_app'] = vnc_app #print("haca kingo vnc_app") #print(emacs_path)3 return_dict['vnc_app'] = "emacs" return_dict['emacs_modes'] = emacs_modes return_dict['emacs_path'] = emacs_path return return_dict
def snap_window(pos: RelativeScreenPos) -> None: """Move the active window to a specific position on-screen. See `RelativeScreenPos` for the structure of this position. """ _snap_window_helper(ui.active_window(), pos)
def refresh_context_mapping(enabled_only = False): global context_mapping global sorted_context_map_keys global show_enabled_contexts_only global cached_window_title cached_short_context_names = {} show_enabled_contexts_only = enabled_only cached_window_title = ui.active_window().title active_contexts = registry.active_contexts() update_active_contexts_cache(active_contexts) context_mapping = {} for context in registry.contexts.values(): short_name = str(context).replace('(Context', '').replace(')', '').split('.')[-1].replace('_', " ") #print(short_name) context_name = str(context) if enabled_only and context in active_contexts or not enabled_only: context_mapping[context_name] = {} for __, val in context.commands_get().items(): #todo figure out why somethings are functions/list if not callable(val.target) and not isinstance(val.target, list): context_mapping[context_name][str(val.rule.rule)] = val.target.code if len(context_mapping[context_name]) == 0: context_mapping.pop(context_name) else: cached_short_context_names[short_name] = context_name ctx.lists['self.help_contexts'] = cached_short_context_names sorted_context_map_keys = sorted(context_mapping)
def move_screen(off): win = ui.active_window() src_screen = win.screen screens = sorted_screens() dst_screen = screens[(screens.index(src_screen) + off) % len(screens)] if src_screen == dst_screen: return src = src_screen.visible_rect dst = dst_screen.visible_rect old = win.rect change_screen_mode = config.get("window_management.change_screen_mode", "same") if change_screen_mode == "same": new_rectangle = ui.Rect( dst.left + (old.left - src.left) / src.width * dst.width, dst.top + (old.top - src.top) / src.height * dst.height, old.width / src.width * dst.width, old.height / src.height * dst.height, ) elif change_screen_mode == "full": new_rectangle = dst else: raise ValueError("{} screen mode not understood." (change_screen_mode)) win.rect = new_rectangle time.sleep(0.25) win.rect = new_rectangle time.sleep(0.25) win.rect = new_rectangle
def file_manager_current_path(): path = ui.active_window().title try: path = path.split(":")[1].lstrip() except: path = "" # print("current: " + path) if "~" in path: # the only way I could find to correctly support the user folder: # get absolute path of ~, and strip /mnt/x from the string abs_usr_path = get_usr_path() abs_usr_path = abs_usr_path[abs_usr_path.find("/home" ):len(abs_usr_path)] path = path.replace("~", abs_usr_path) path = get_win_path(path) if path in directories_to_remap: path = directories_to_remap[path] if path in directories_to_exclude: path = "" return path
def offset_x(self): """Find the current windows x offset :returns: the current window x offset """ pos = ui.active_window().rect.x return 0
def offset_y(self): """Find the current windows y offset :returns: the current window y offset """ pos = ui.active_window().rect.y return 0
def find_active_window_rect() -> TalonRect: """ The Talon active window rect detector is buggy under LInux. So allow getting it a different way. """ if setting_win_rect_workaround.get() == 1: import subprocess active_window_id = subprocess.run(["xdotool", "getactivewindow"], capture_output=True, check=True).stdout.strip() active_window_geom = subprocess.run( ["xdotool", "getwindowgeometry", "--shell", active_window_id], capture_output=True, check=True).stdout val_map = { key.decode("utf8"): int(val) for line in active_window_geom.splitlines() for key, val in (line.split(b"="), ) } return TalonRect( val_map["X"], val_map["Y"], val_map["WIDTH"], val_map["HEIGHT"], ) else: return ui.active_window().rect
def refresh_context_command_map(enabled_only=False): global rule_word_map global context_command_map global context_map global sorted_context_map_keys global show_enabled_contexts_only global cached_window_title global context_map context_map = {} cached_short_context_names = {} show_enabled_contexts_only = enabled_only cached_window_title = ui.active_window().title active_contexts = registry.active_contexts() # print(str(active_contexts)) update_active_contexts_cache(active_contexts) context_command_map = {} for context_name, context in registry.contexts.items(): splits = context_name.split(".") index = -1 if "talon" in splits[index]: index = -2 short_name = splits[index].replace("_", " ") else: short_name = splits[index].replace("_", " ") if "mac" == short_name or "win" == short_name or "linux" == short_name: index = index - 1 short_name = splits[index].replace("_", " ") # print("short name: " + short_name) if short_name in overrides: short_name = overrides[short_name] if context in active_contexts or not enabled_only: context_command_map[context_name] = {} for command_alias, val in context.commands.items(): # print(str(val)) if command_alias in registry.commands: # print(str(val.rule.rule) + ": " + val.target.code) context_command_map[context_name][ str(val.rule.rule) ] = val.target.code # print(short_name) # print("length: " + str(len(context_command_map[context_name]))) #if len(context_command_map[context_name]) == 0: # context_command_map.pop(context_name) #else: # cached_short_context_names[short_name] = context_name # context_map[context_name] = context cached_short_context_names[short_name] = context_name context_map[context_name] = context refresh_rule_word_map(context_command_map) ctx.lists["self.help_contexts"] = cached_short_context_names # print(str(ctx.lists["self.help_contexts"])) sorted_context_map_keys = sorted(cached_short_context_names)
def warps(self): try: window = ui.active_window() bundle = window.app.bundle return self.data[bundle].keys() except Exception as e: print(e) return []
def get_url(win=None): if win is None: win = ui.active_window() children = win.children.find(AXRole="AXTextField") if children: return children[0].AXValue else: return None
def resize_window(x, y, w, h): win = ui.active_window() rect = win.screen.visible_rect.copy() rect.x += rect.width * x rect.y += rect.height * y rect.width *= w rect.height *= h win.rect = rect
def _bring_forward(window): current_window = ui.active_window() try: window.focus() current_window.focus() except Exception as e: # We don't want to block if this fails. print(f"Couldn't bring window to front: {e}")
def file_ext(): title = ui.active_window().title m = regex_ext.search(title) if m: return m.group(3) return ""
def _toggle_slack_dnd(m): window = ui.active_window() # Open a slack window to yourself in a browser, scrape these values out of it. subprocess.call(["open", "slack://channel?id=D865P648K&team=T03R7LB3M"]) time.sleep(1) Str(f"/dnd {amount}\n")(None) Key("cmd-[")(None) window.focus()
def switcher_focus_window(window: ui.Window): """Focus window and wait until switch is made""" window.focus() t1 = time.monotonic() while ui.active_window() != window: if time.monotonic() - t1 > 1: raise RuntimeError(f"Can't focus window: {window.title}") actions.sleep(0.1)
def slack_close_right_sidebar(): "close right sidebar" rect = ui.active_window().rect old_x, old_y = ctrl.mouse_pos() x = rect.width - 30 ctrl.mouse_move(x, 123) ctrl.mouse_click() ctrl.mouse_move(old_x, old_y)
def get_url(win=None): if win is None: win = ui.active_window() if win.app.bundle in BROWSERS: return win.children.find(AXTitle="Address and search bar")[0].AXValue else: raise ValueError("no method for getting url from not chrome yet")
def copy_current_app_info() -> None: """Copy all info for the current app.""" active_app = ui.active_app() info = "\n".join([ 'Bundle: "{}"'.format(active_app.bundle), 'Exe: "{}"'.format(active_app.exe), 'Title: "{}"'.format(ui.active_window().title), ]) _print_and_copy(info)
def get_active_mode(self): title = ui.active_window().title mode = None if "MODE:" in title: mode = title.split("MODE:")[1].split(" ")[0] if mode not in self.vim_modes.keys(): return None self.current_mode = mode return mode