def _maybe_record(): """In the right context, start recording on every mic, otherwise stop.""" global _last_transition if "user._noise_recorder_context" in scope.get("tag", []): # Assume it's a fullscreen video if the window is on the PRIMARY screen, # and matches the fullscreen dimensions. This may require the primary # screen to have a toolbar to work properly. app = ui.active_app() window = app.active_window should_record = 0 == window.rect.compare_to_rect(ui.main_screen().rect) else: should_record = False # The window dimensions can bounce around during the transitions to & from # fullscreen, so deadzones are used for debouncing. if should_record: if (not recording() and time.monotonic() > _last_transition + TRANSITION_DEADZONE): _last_transition = time.monotonic() noise, existing = noise_with_least_data() LOGGER.info(f'Recording noise with the least data: "{noise}", ' f"{existing / 60:0.1f} mins exist already.") record(noise) # TODO: Probably enable a tag here so people can hook behaviour elif recording( ) and time.monotonic() > _last_transition + TRANSITION_DEADZONE: _last_transition = time.monotonic() stop() # Lambda is used becayse Python thinks `print_total_noise_recorded` # isn't callable. cron.after("2s", actions.self.print_total_noise_recorded)
def reset(self, _): self.offset_x = self.main_screen.width // 2 self.offset_y = self.main_screen.height // 2 self.angle = 0 self.speed = 0.0 self.main_screen = ui.main_screen() ctrl.cursor_visible(True)
def show_commands(context): # what you say is stored as a trigger # TODO: switch to list of tuples to simplify paging? mapping = [] for trigger in context.triggers.keys(): action = context.mapping[context.triggers[trigger]] mapping.append(( trigger, format_action(action), )) keymap = { '(show quit | show exit)': lambda x: close_webview(), 'up': Key('pgup'), 'down': Key('pgdown'), } main = ui.main_screen().visible_rect # need to account for header and footer / pagination links, hence '-2' max_items = int(main.height // (FONT_SIZE + 2 * BORDER_SIZE) - 2) if len(mapping) >= max_items: # use all visible space webview.resize(x=main.x, y=main.y, w=main.width, h=main.height) total_pages = int(len(mapping) // max_items) if (len(mapping) % max_items > 0): total_pages += 1 pages = [] for page in range(1, total_pages + 1): pages.append(mapping[((page - 1) * max_items):((page) * max_items)]) for idx, items in enumerate( pages ): # items = mapping[((page-1)*max_items):((page)*max_items)] page = idx + 1 keymap.update({ 'page ' + str(page): create_render_page(context, items, page, total_pages) }) render_page(context, pages[0], 1, total_pages) else: view_height = (len(mapping) + 2) * FONT_SIZE webview.resize(x=main.x, y=(main.height - view_height) / 2, w=main.width, h=view_height) webview.render(templates['commands'], context_name=context.name, mapping=mapping) webview_context.keymap(keymap) webview_context.load() webview.show()
def reset(self, _): self.save_last() self.offset_x = self.main_screen.x self.offset_y = self.main_screen.y self.main_screen = ui.main_screen() self.width = self.main_screen.width self.height = self.main_screen.height
def reset(self, _): self.save_state() self.count = 0 self.offset_x = 0 self.offset_y = 0 self.main_screen = ui.main_screen() self.width = self.main_screen.width self.height = self.main_screen.height
def __init__(self): self.main_screen = ui.main_screen() self.offset_x = 0 self.offset_y = 0 self.width = self.main_screen.width self.height = self.main_screen.height self.save_last() self.mcanvas = canvas.Canvas.from_screen(self.main_screen) self.active = False
def render_page(context, mapping, current_page, total_pages): main = ui.main_screen().visible_rect webview.render( templates["commands"], context_name=context.name, mapping=mapping, current_page=current_page, total_pages=total_pages, )
def __init__(self, seconds=4, rate=44100): self.width = int(ui.main_screen().width) self.chunk = int((seconds * rate) / self.width) self.history = [] self.tmp = [] self.events = [] self.lock = threading.Lock() self.odd = False self.hissing = False
def resize(self, width: int, height: int): if not self.need_resize: return self.need_resize = False screen = ui.main_screen() rect = ui.Rect( screen.x + (screen.width - width) / 2, screen.y + (screen.height - height) / 2, width, height, ) self.canvas.rect = rect
def __init__(self): """Set up sleep states""" self.nosignal = 0 # Number of ticks there have been no signal self.sleeping = False self.main_screen = ui.main_screen() self.size_px = Point2d(self.main_screen.width, self.main_screen.height) self.settings = { "max_eyeless_ticks": settings.get( "user.mouse_sleep_tracker_timeout_frames" ), "sleep_mode": settings.get("user.mouse_sleep_tracker_sleep_mode"), "suspend_screen": settings.get("user.mouse_sleep_tracker_suspend_screen"), }
def __init__(self): self.states = [] self.main_screen = ui.main_screen() self.offset_x = 0 self.offset_y = 0 self.width = self.main_screen.width self.height = self.main_screen.height self.states.append( (self.offset_x, self.offset_y, self.width, self.height)) self.mcanvas = canvas.Canvas.from_screen(self.main_screen) self.active = False self.moving = False self.count = 0
def _maybe_record(): """In the right context, start recording on every mic, otherwise stop.""" global _last_transition, _original_mic, _gui_text # The window dimensions can bounce around during the transitions to & from # fullscreen, so deadzones are used for debouncing. if ( "user._noise_recorder_context" in scope.get("tag", []) and # Assume it's a fullscreen video if the window is on the PRIMARY screen, # and matches the fullscreen dimensions. This basically assumes the # primary screen has a toolbar. ui.active_app().active_window.rect == ui.main_screen().rect ): if ( not recording() and time.monotonic() > _last_transition + TRANSITION_DEADZONE ): _last_transition = time.monotonic() active_mic = microphone.manager.active_mic() _original_mic = active_mic.name if active_mic else None print("Disabling mic while recording noises.") actions.speech.set_microphone("None") with _gui_lock: # This can take a while (e.g. on a cold disk drive) so pop a # message _gui_text = "Scanning noise recordings on disk, this may be slow..." gui.show() noise, existing = noise_with_least_data() LOGGER.info( f'Recording noise with the least data: "{noise}", ' f"{existing / 60:0.1f} mins exist already." ) record(noise) context.tags.add("user.recording_noises") elif recording() and time.monotonic() > _last_transition + TRANSITION_DEADZONE: _last_transition = time.monotonic() context.tags.remove("user.recording_noises") stop() gui.hide() with _gui_lock: _gui_text = None print("Re-enabling microphone.") if _original_mic: actions.speech.set_microphone(_original_mic) _original_mic = None else: # Shouldn't ever get here but just use this as a fallback print('No previous mic found. Switching to "System Default"') actions.speech.set_microphone("System Default")
def move_to_ocr(m): old_pos = ctrl.mouse_pos() start = time.time() screen = ui.main_screen() factor = 1 if (int(screen.width), int(screen.height)) == RETINA_SIZE: factor = RETINA_FACTOR midpoint = None bounds = [screen.x, screen.y, screen.width, screen.height] which = int(parse_word(m._words[1])) row = int(which - 1) // 3 col = int(which - 1) % 3 bounds = [ screen.x + int(col * screen.width // 3), screen.y + int(row * screen.height // 3), screen.width // 3, screen.height // 3, ] midpoint = (bounds[0] + bounds[2] // 2, bounds[1] + bounds[3] // 2) print(which, row, col, bounds, midpoint) # noinspection PyProtectedMember search = join_words(list(map(parse_word, m.dgnwords[0]._words))).lower().strip() ctrl.mouse_move(*midpoint) print(f"Starting teleport {which} to {search}") hocr = ocr_screen(*bounds, factor=factor) print(f"... OCR'd screen: {time.time() - start} seconds.") tree = ElementTree.XML(hocr) # type: list[ElementTree.Element] # print(list(tree[1])) best_pos = None best_distance = screen.width + screen.height for span in tree[1].iter(): # print(span, span.attrib.get("class", "")) if span.attrib.get("class", "") == "ocrx_word": if search in span.text.lower(): # title is something like"bbox 72 3366 164 3401; x_wconf 95" title = span.attrib["title"] # type: str x, y, side, bottom = [ int(i) / (SCALE * factor) for i in title.split(";")[0].split()[1:] ] candidate = bounds[0] + (x + side) / 2, bounds[1] + (y + bottom) / 2 dist = distance(candidate, midpoint) if dist < best_distance: # print(search, span.text, span.attrib["title"]) best_pos = candidate if best_pos is not None: print(f"... Found match, moving to {best_pos}. {time.time() - start} seconds.") ctrl.mouse_move(best_pos[0], best_pos[1]) return print(f"... No match. {time.time() - start} seconds.") ctrl.mouse_move(*old_pos)
def __init__(self): self.main_screen = ui.main_screen() self.offset_x = self.main_screen.width // 2 self.offset_y = self.main_screen.height // 2 self.angle = 0 self.speed = 0.0 self.mcanvas = canvas.Canvas.from_screen(self.main_screen) self.active = False self.last_draw = time.time() self.accel = Acceleration(cd=(.001, 100.0), v=(0.0004, 0.0025), lmb=1000.0, ratio=0.3) self.hiss_start = time.time() noise.register("noise", self.on_noise)
def show_commands(context): # what you say is stored as a trigger mapping = [] for trigger in context.triggers.keys(): action = context.mapping[context.triggers[trigger]] mapping.append((trigger, format_action(action))) keymap = { "(0 | quit | exit | escape)": lambda x: close_webview(), "up": Key("pgup"), "down": Key("pgdown"), } main = ui.main_screen().visible_rect # need to account for header and footer / pagination links, hence '-2' max_items = int(main.height // (FONT_SIZE + 2 * BORDER_SIZE) - 2) if len(mapping) >= max_items: total_pages = int(len(mapping) // max_items) if len(mapping) % max_items > 0: total_pages += 1 pages = [] # add elements to each page based on the page index for page in range(1, total_pages + 1): pages.append(mapping[((page - 1) * max_items):((page) * max_items)]) # create the commands to navigate through pages for idx, items in enumerate(pages): page = idx + 1 keymap.update({ "page " + str(page): create_render_page(context, items, page, total_pages) }) render_page(context, pages[0], 1, total_pages) else: view_height = (len(mapping) + 2) * FONT_SIZE webview.render(templates["commands"], context_name=context.name, mapping=mapping) webview_context.keymap(keymap) webview_context.load() webview.show()
def absolute_position(corner: str): """Get the absolute position of a corner. :returns tuple[int, int]: the position of this corner. """ screen = ui.main_screen().rect if corner == Corner.TOP_LEFT: return (0, 0) elif corner == Corner.TOP_RIGHT: return (screen.width, 0) elif corner == Corner.BOTTOM_LEFT: return (0, screen.height) elif corner == Corner.BOTTOM_RIGHT: return (screen.width, screen.height) else: raise ValueError(f'Invalid corner: "{corner}"')
def __init__(self): self.main_screen = ui.main_screen() self.center_x = self.main_screen.x + self.main_screen.width // 2 self.center_y = self.main_screen.y + self.main_screen.height // 2 self.offset_x = self.center_x self.offset_y = self.center_y self.first_hiss = True self.hiss_job = None self.angle = 0 self.radius = 15 self.mcanvas = canvas.Canvas.from_screen(self.main_screen) self.active = False self.last_draw = time.time() self.accel = Acceleration(cd=(0.001, 100.0), v=(0.0004, 0.0025), lmb=1000.0, ratio=0.3) noise.register("noise", self.on_noise)
def draw(self, canvas): text = self.history[:] if not text or not self.enabled: return paint = canvas.paint paint.filter_quality = paint.FilterQuality.LOW paint.textsize = 15 paint.antialias = True # canvas.draw_rect(ui.Rect(x - 50, y - 50, 100, 100)) x = canvas.x + 20 y = canvas.y + 50 text_pad = 0 rect_pad = 10 # measure text width = 0 text_top = y text_bot = y line_spacing = 0 for line in text: _, trect = paint.measure_text(line) width = max(width, trect.width) line_spacing = max(line_spacing, trect.height) text_top = min(text_top, y - trect.height) x = canvas.x + ui.main_screen().width - 2 * rect_pad - width line_spacing += text_pad text_bot = y + (len(text) - 1) * line_spacing height = text_bot - text_top rect = ui.Rect(x - rect_pad, text_top - 2, width + rect_pad * 2, height + rect_pad + 2) paint.color = 'ffffffbb' paint.style = paint.Style.FILL canvas.draw_round_rect(rect, 10, 10) paint.color = '000000' paint.style = paint.Style.FILL for line in text: canvas.draw_text(line, x, y) y += line_spacing
def print_mouse_positions() -> None: """Print the mouse position relative to each corner. Use to get hard-codable positions. """ mouse_pos = ctrl.mouse_pos() print(f"Absolute mouse pos: {mouse_pos}") screen = ui.main_screen().rect print(f"Main screen: {screen}") for corner in [ Corner.TOP_LEFT, Corner.TOP_RIGHT, Corner.BOTTOM_LEFT, Corner.BOTTOM_RIGHT, ]: corner_pos = Corner.absolute_position(corner) relative = (mouse_pos[0] - corner_pos[0], mouse_pos[1] - corner_pos[1]) print(f"Position relative to {corner}: {relative}")
def __init__(self): # tweakable variables self.beep = False # requires windows self.two_blinks = ( True # depricated - one blink means you will have lots of misclicks ) self.magic = 24 # works on 4c might not be optimized # CHANGME if not clicking accuratley (won't work on 4C speed probably like =35) self.scroll_sensitivity = 1 # I like it kinda fast. 6-7 slower. # state tracking self.second = False self.blinking = False self.nosignal = 0 self.sleep = False self.right_px, self.right_py = 0, 0 self.lcurclosed = 0 self.rcurclosed = 0 self.signal = 0 self.left_px, self.left_py = 0, 0 self.counter = 0 self.invalid_left = 0 self.invalid_right = 0 self.left_closed_count = 0 self.right_closed_count = 0 self.expire = 700 # lower if you blink twice a lot self.focus_sensitivity = 48 # can go lower on 4C Tobii 5 recomended = 50 self.MAXSIZE = 120 # if memory starts to be a problem self.eye_history = [] self.main_screen = ui.main_screen() self.size_px = Point2d(self.main_screen.width, self.main_screen.height) self.get_time = lambda: int(round(time() * 1000)) self.current_time = 0 self.first_blink = 0 self.eyes = True self.last_blink = False self.right_history = self.momentum_state() self.left_history = self.momentum_state() self.right_open = 1 self.left_open = 1
def start_setup(self, setup_type, mouse_position=None): """Starts a setup mode that is used for moving, resizing and other various changes that the user might setup""" if (mouse_position is not None): self.drag_position = [ mouse_position[0] - self.limit_x, mouse_position[1] - self.limit_y ] if (setup_type not in self.allowed_setup_options and setup_type not in ["", "cancel", "reload"]): return pos = ctrl.mouse_pos() # Persist the user preferences when we end our setup if (self.setup_type != "" and not setup_type): self.drag_position = [] rect = self.canvas.rect if (self.setup_type == "dimension"): self.x = 0 self.y = 0 self.width = int(rect.width) self.height = int(rect.height) self.limit_width = int(rect.width) self.limit_height = int(rect.height) self.preferences.width = self.limit_width self.preferences.height = self.limit_height self.preferences.limit_width = self.limit_width self.preferences.limit_height = self.limit_height elif (self.setup_type == "font_size"): self.preferences.font_size = self.font_size self.setup_type = setup_type self.preferences.mark_changed = True self.canvas.pause() self.canvas.unregister("draw", self.setup_draw_cycle) self.canvas = None self.event_dispatch.request_persist_preferences() # Cancel every change elif setup_type == "cancel": self.drag_position = [] if (self.setup_type != ""): self.load({}, False) self.setup_type = "" if self.canvas: self.canvas.unregister("draw", self.setup_draw_cycle) self.canvas = None for canvas_reference in self.canvases: canvas_rect = self.align_region_canvas_rect( canvas_reference["region"]) canvas_reference["canvas"].rect = canvas_rect canvas_reference["canvas"].freeze() elif setup_type == "reload": self.drag_position = [] self.setup_type = "" for canvas_reference in self.canvases: canvas_reference["canvas"].freeze() # Start the setup by mocking a full screen screen region to place the canvas in else: main_screen = ui.main_screen() region = HudScreenRegion("setup", "Setup mode text", "command_icon", "DD4500", main_screen.rect, \ Point2d(main_screen.rect.x, main_screen.rect.y)) region.vertical_centered = True canvas_rect = self.align_region_canvas_rect(region) self.x = canvas_rect.x self.y = canvas_rect.y if not self.canvas: self.canvas = canvas.Canvas(self.x, self.y, self.limit_width, self.limit_height) self.canvas.register("draw", self.setup_draw_cycle) self.canvas.move(self.x, self.y) self.canvas.resume() super().start_setup(setup_type, mouse_position)
</style> <h3 id="title">History</h3> <table> {% for phrase in phrases %} <tr><td class="phrase">{{ phrase }}</td></tr> {% endfor %} <tr><td><i>{{ hypothesis }}</i></td></tr> </ul> """ if WEBVIEW: webview = webview.Webview() webview.render(template, phrases=["command"]) webview.show() webview.move(1, ui.main_screen().height) class History: def __init__(self): self.visible = True self.history = [] engine.register("post:phrase", self.on_phrase_post) def parse_phrase(self, phrase): return " ".join(word.split("\\")[0] for word in phrase) def on_phrase_post(self, j): phrase = self.parse_phrase(j.get("phrase", [])) cmd = j["cmd"] if cmd == "p.end" and phrase:
body { width: 200px; padding: 0; margin: 0; } </style> <h3 id="title">DICTATION ON!</h3> <br> <br> Greedy: {{ greedy }} <br> <br> <br> """ webview = Webview() webview.move(ui.main_screen().width - 250, ui.main_screen().height - 270) def update_context_and_webview(): ctx1.reload() ctx2.reload() ctx3.reload() if config.dictation_enabled: webview.render(template, greedy=str(config.greedy)) webview.show() else: webview.hide() def toggle_greedy(TRUEFALSE):
def mouse_center(): """move the mouse cursor to the center of the currently active window""" rect = ui.main_screen().rect center = (rect.x + rect.width / 2, rect.y + rect.height / 2) ctrl.mouse_move(center)
} </style> <table> {% for phrase in phrases %} <tr><td class="phrase">{{ phrase }}</td></tr> {% endfor %} <tr><td><i>{{ hypothesis }}</i></td></tr> </ul> ''' if SHOW: webview = webview.Webview() webview.render(template, phrases=['waiting...']) webview.show() webview.move(ui.main_screen().width - 100, ui.main_screen().height) class History: def __init__(self): self.history = [] engine.register('post:phrase', self.on_phrase_post) def parse_phrase(self, phrase): return ' '.join(word.split('\\')[0] for word in phrase) def on_phrase_post(self, j): phrase = self.parse_phrase(j.get('phrase', [])) cmd = j['cmd'] if cmd == 'p.end' and phrase: self.history.append(phrase) self.history = self.history[-hist_len:]
import string import talon from talon import voice, ui from talon.voice import Context from talon.webview import Webview from .misc.basic_keys import alpha_alt # reusable constant for font size (in pixels), to use in calculations FONT_SIZE = 15 # border spacing, in pixels BORDER_SIZE = int(FONT_SIZE / 6) main = ui.main_screen().visible_rect # need to account for header and footer / pagination links, hence '-2' MAX_ITEMS = int(main.height // (FONT_SIZE + 2 * BORDER_SIZE) - 2) ctx = Context("help") webview_context = Context("helpWebView") def on_click(data): if data["id"] == "close": return close_webview() elif "page" in data["id"]: context, _, page = data["id"].split("-") if context == "contexts": return render_contexts_help(_, int(page)) return render_commands_webview(get_context(context), int(page)) else: return render_commands_webview(voice.talon.subs.get(data["id"]))
r = webview.rect new_location = {"x": r.x, "y": r.y} webview_location = webview_locations[key] if (webview_location["x"] != new_location["x"] or webview_location["y"] != new_location["y"]): webview_locations[key] = new_location config.save_config_json("webview_locations.json", webview_locations) webview = webview.Webview() webview.render(template, phrases=["command"]) webview.show() key = screen_key() if key not in webview_locations: webview_locations[key] = {"x": 1, "y": ui.main_screen().height} print("moving webview_locations", webview_locations[key]) webview.move(webview_locations[key]["x"], webview_locations[key]["y"]) webview.register("blur", webview_blur) class History: def __init__(self): self.visible = True self.history = [] engine.register("post:phrase", self.on_phrase_post) def parse_phrase(self, phrase): return " ".join(word.split("\\")[0] for word in phrase)
def __init__(self): self.history = [] engine.register('post:phrase', self.on_phrase_post) self.canvas = Canvas.from_screen(ui.main_screen()) self.canvas.register('draw', self.draw)
return call_it() if debounced._timer is None: debounced._timer = threading.Timer(wait - time_since_last_call, call_it) debounced._timer.start() debounced._timer = None debounced._last_call = 0 return debounced return decorator screen = ui.main_screen() size_px = Point2d(screen.width, screen.height) transparent = '01' not_transparent = '40' regular_size = 7 demo_size = 30 last_click = None # Shows crazy circles def smooth_location(): # Calculate smooth location of point
from talon import Module, actions, imgui, Module, scope, ui mod = Module() mod.mode("help_scope", "Mode for showing the scope help gui") setting_max_length = mod.setting( "help_scope_max_length", type=int, default=50, ) @imgui.open(x=ui.main_screen().x) def gui(gui: imgui.GUI): gui.text("Scope") gui.line() gui.spacer() gui.text("Modes") gui.line() for mode in sorted(scope.get("mode")): gui.text(mode) gui.spacer() gui.text("Tags") gui.line() for tag in sorted(scope.get("tag")): gui.text(tag) gui.spacer() gui.text("Misc") gui.line() ignore = {"main", "mode", "tag"} keys = {*scope.data.keys(), *scope.data["main"].keys()}