Exemplo n.º 1
0
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"))
Exemplo n.º 2
0
def set_voice_type(type, silent=None):
    global voice_type, last_voice_type
    if voice_type != VoiceType.SLEEPING:
        last_voice_type = voice_type
    voice_type = type

    talon_enabled = type == VoiceType.TALON
    dragon_enabled = type == VoiceType.DRAGON
    dictation_enabled = type == VoiceType.DICTATION

    global speech
    speech.set_enabled(type == VoiceType.TALON or type == VoiceType.DICTATION)

    global dictation_group
    if not dictation_enabled:
        dictation_group.disable()

    global engine
    if dragon_enabled:
        engine.mimic("wake up".split())
    elif last_voice_type == VoiceType.DRAGON:
        # else:
        engine.mimic("go to sleep".split())

    if dictation_enabled:
        # Without postponing this "go to sleep" will be printed
        cron.after("0s", lambda: dictation_group.enable())

    if silent == None:
        show_mode_message()
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
    def update_screenshot(self):
        def finish_capture():
            self.img = screen.capture_rect(self.rect)
            self.mcanvas.freeze()

        self.mcanvas.hide()
        cron.after("16ms", finish_capture)
Exemplo n.º 5
0
def make_selection(index: int):
    global active_word_list
    cron.after("0s", close_homophones)
    if is_selection:
        clip.set(active_word_list[index - 1])

    actions.insert(active_word_list[index - 1])
Exemplo n.º 6
0
def reset_gui_timer():
    global phrase_nonce
    if gui_enabled:
        phrase_nonce += 1
        nonce = phrase_nonce
        gui.show()
        cron.after(f"{auto_hide_delay.get()}s", lambda: maybe_hide(nonce))
Exemplo n.º 7
0
def _log(args):
    global text, can
    if "command" not in scope.get("mode"):
        return
    text = f"\"{' '.join(args['text'])}\""
    can.show()
    can.freeze()
    actions.sleep(action_wait)
    cron.after(canvas_hide_wait, hide_canvas)
Exemplo n.º 8
0
 def do_capture():
     print(
         "capturing area",
         self.offset_x,
         self.offset_y,
         self.width,
         self.height,
     )
     self.img = screen.capture(self.offset_x, self.offset_y,
                               self.width, self.height)
     cron.after("5ms", finish_capture)
Exemplo n.º 9
0
def make_selection(m, choices, callback):
    cron.after("0s", close_choices)
    words = m._words
    d = None
    if len(words) == 1:
        d = int(parse_word(words[0]))
    else:
        d = int(parse_word(words[1]))

    choice = choices[d - 1]
    callback(choice)
Exemplo n.º 10
0
def make_selection(m, is_selection, transform=lambda x: x):
    cron.after("0s", close_homophones)
    words = m._words
    d = None
    if len(words) == 1:
        d = int(parse_word(words[0]))
    else:
        d = int(parse_word(words[1]))
    w = active_word_list[d - 1]
    if len(words) > 1:
        w = transform(w)
    insert(w, is_selection)
Exemplo n.º 11
0
def make_selection(m):
    cron.after("0s", close_directories)
    words = m._words
    d = None
    if len(words) == 1:
        d = int(parse_word(words[0]))
    else:
        d = int(parse_word(words[1]))
    w = active_word_list[d - 1]

    cd_statement = f"cd {dirs[w]} && ls"
    insert(cd_statement)
Exemplo n.º 12
0
def make_selection(m):
    cron.after("0s", close_directories)
    words = m._words
    print("CLIPBOARD:", CLIPBOARD)
    d = None
    if len(words) == 1:
        d = int(parse_word(words[0]))
    else:
        d = int(parse_word(words[1]))
    w = CLIPBOARD[d - 1]

    Str(w)(None)
Exemplo n.º 13
0
    def _write_frames(self):
        """Write the frames so far to a file & clear them."""
        sample_rate = 16000
        # Ignore short recordings, these are probably accidental.
        if len(self._frames) >= sample_rate * MINIMUM_RECORDING_LENGTH:
            path = self._get_chunk_path()
            # TODO: Do this on a delay later
            #   ^ What did I mean by this???
            frames = self._frames
            self._frames = []
            # TODO: Spawn thread for this? stopping the stream may also be slow.
            LOGGER.info(f"Writing noise file: {path}")
            flac.write_flac(
                str(path), frames, sample_rate=sample_rate, compression_level=1
            )

            # This will fire once per device, so deadzone it.
            duration = len(frames) / sample_rate
            # HACK: Sometimes Windows will suppress this notification so throw
            #   it on a delay. (The delay also allows us the report of the total
            #   to factor in all mics in this session.)
            #
            # TODO: Add up time from all split recordings
            #
            # TODO: Organisation of this notification scheme is gross. At some
            #   point rewrite it.
            noise_name = self.noise_name

            def report_success():
                nonlocal duration, noise_name
                total_hours = total_data() / 60 / 60
                num_mics = len(amounts_recorded_by_device())
                _notify_with_deadzone(
                    "Noise Recorded",
                    # TODO: Read this from disk to take into account multiple chunks
                    f'Recorded {duration:0.0f} seconds of: "{noise_name}" ({duration/60:0.1f} mins). Say "delete last recording" to discard it. All noises: {total_hours:0.1f} hours across {num_mics} mics.',
                ),

            cron.after("500ms", report_success)
        else:
            LOGGER.info(
                f"Recording under {MINIMUM_RECORDING_LENGTH} seconds, file not written: {self}"
            )
            # HACK: Sometimes Windows will suppress this notification so throw
            #   it on a delay.
            cron.after(
                "500ms",
                # This will fire once per device, so deadzone it.
                lambda: _notify_with_deadzone(
                    "Recording Discarded",
                    f'Recording under {MINIMUM_RECORDING_LENGTH} seconds, discarding: "{self.noise_name}"',
                ),
            )
Exemplo n.º 14
0
def terminal_hotkey(_, e):
    """Adds an alt-w to pick up zle selection as well."""
    window = ui.active_window()
    bundle = window.app.bundle
    if bundle != "com.googlecode.iterm2":
        return
    if e == "cmd-c" and e.up:
        # print("intercept " + str(e))
        Key("alt-w")(None)
    elif e == "enter" and e.up:
        # print("intercept " + str(e))
        cron.after("500ms", lambda: update_ctx(None))
    return True
Exemplo n.º 15
0
 def check_step(self, phrase):
     """Check if contents in the phrase match the voice commands available in the step"""
     if self.current_walkthrough is not None and self.is_in_right_context():
         phrase_to_check = " ".join(phrase["phrase"]).lower()
         if self.current_stepnumber < len(self.current_walkthrough.steps):
             step = self.current_walkthrough.steps[self.current_stepnumber]
             
             current_length = len(self.current_words)
             for index, voice_command in enumerate(step.voice_commands):
                 # Make sure the activations can only happen in-order
                 if index >= current_length:
                     if voice_command in phrase_to_check:
                         self.current_words.append(voice_command)
                         phrase_to_check = phrase_to_check.split(voice_command, 1)[1]
                     else:
                         break
             
             # Send an update about the voice commands said during the step if it has changed
             if current_length != len(self.current_words):
                 step.said_walkthrough_commands = self.current_words[:]
                 self.content.publish_event("walkthrough_step", "walkthrough_step", "replace", copy.copy(step), show=True, claim=True)
                 
                 # Skip to the next step if no voice commands are available
                 voice_commands_remaining = copy.copy(step.voice_commands)
                 all_commands_said = False
                 for said_word in self.current_words:
                     if said_word in voice_commands_remaining:
                         voice_commands_remaining.remove(said_word)
                 
                 if len(step.voice_commands) > 0 and len(voice_commands_remaining) == 0 and not "skip step" in step.voice_commands and not "continue" in step.voice_commands:
                     cron.cancel(self.next_step_job)
                     self.next_step_job = cron.after("1500ms", self.next_step)
Exemplo n.º 16
0
 def on_finish(self):
     if self._gap_tolerance:
         with self._job_lock:
             self._end_job = cron.after(f"{self._gap_tolerance}ms",
                                        self._exit_safe)
     else:
         self._exit_safe()
Exemplo n.º 17
0
    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)
Exemplo n.º 18
0
 def repeat(self):
     repeater = Rep(1)
     repeater.ctx = talon
     repeater(None)
     if self.job:
         self.job = cron.after(self.repeat_delay, self.repeat)
         print('REPEAT')
Exemplo n.º 19
0
def make_selection(m, is_selection, transform=lambda x: x):
    cron.after("0s", close_homophones)
    words = m._words
    d = None
    if len(words) == 1:
        d = int(parse_word(words[0]))
    else:
        d = int(parse_word(words[1]))
    w = active_word_list[d - 1]
    if len(words) > 1:
        w = transform(w)
    if is_selection:
        clip.set(w)
        press("cmd-v", wait=0)
    else:
        Str(w)(None)
Exemplo n.º 20
0
    def hud_environment_change(self, hud_environment: str):
        if self.current_talon_hud_environment != hud_environment:
            self.set_current_flow("environment_changed")
            self.current_talon_hud_environment = hud_environment

            # Add a debouncer for the environment change to reduce flickering on transitioning
            cron.cancel(self.update_environment_debouncer)
            self.update_environment_debouncer = cron.after(
                "200ms", self.debounce_environment_change)
Exemplo n.º 21
0
 def on_noise(self, noise):
     if noise == 'hiss_start' and talon.enabled:
         if self.job is None:
             self.job = cron.after(self.initial_delay, self.repeat)
             print('HISS START')
     elif noise == 'hiss_end' and self.job:
         print('HISS STOP')
         cron.cancel(self.job)
         self.job = None
Exemplo n.º 22
0
    def on_draw(c):
        c.paint.typeface = "arial"
        # The min(width, height) is to not get gigantic size on portrait screens
        c.paint.textsize = round(min(c.width, c.height) / 2)
        text = f"{number}"
        rect = c.paint.measure_text(text)[1]
        x = c.x + c.width / 2 - rect.x - rect.width / 2
        y = c.y + c.height / 2 + rect.height / 2

        c.paint.style = c.paint.Style.FILL
        c.paint.color = "eeeeee"
        c.draw_text(text, x, y)

        c.paint.style = c.paint.Style.STROKE
        c.paint.color = "000000"
        c.draw_text(text, x, y)

        cron.after("3s", canvas.close)
Exemplo n.º 23
0
    def rephrase(phrase: Phrase, run_async: bool = False):
        """Re-evaluate and run phrase"""
        try:
            current_phrase = phrase_stack[-1]
            ts = current_phrase["_ts"]
            start = phrase.words[0].start - ts
            end   = phrase.words[-1].end - ts
            samples = current_phrase["samples"]
            pstart  = int(start * 16_000)
            pend    = int(end   * 16_000)
            samples = samples[pstart:pend]
        except KeyError:
            return

        if run_async:
            cron.after("0ms", lambda: speech_system._on_audio_frame(samples))
        else:
            speech_system._on_audio_frame(samples)
Exemplo n.º 24
0
    def default_click(click_info: Click):
        modifiers = click_info.modifiers
        actions.self.queue_zoom_action(lambda: click_info.function(modifiers))

        # If we're dragging, it means we intend to drop, so we can queue both
        # at once.
        #
        # HACK: Intercepting the function here is pretty hacky.
        #
        # TODO: Remove `str` cast once action path comparison works
        if str(click_info.function) == str(actions.user.drag):

            def queue_drop():
                nonlocal modifiers
                actions.user.queue_zoom_action(lambda: actions.user.drop(modifiers))

            # Add drop on a delay so the ding rings twice.
            cron.after("150ms", queue_drop)
Exemplo n.º 25
0
 def start(self):
     print(talon.last)
     if self.job is None:
         self.action, self.rule = talon.last_action[0]
         print('START')
         repeat_context.keymap({
             'stop': lambda m: self.stop(),
         })
         repeat_context.load()
         self.job = cron.after(self.initial_delay, self.repeat)
Exemplo n.º 26
0
    def enable(self, persisted=False):
        if not self.enabled:
            self.enabled = True
            self.display_state.register("broadcast_update",
                                        self.broadcast_update)

            # Only reset the talon HUD environment after a user action
            # And only set the visible tag
            self.current_talon_hud_environment = settings.get(
                "user.talon_hud_environment", "")

            if persisted:
                self.set_current_flow("enabled")
                self.current_flow = "enable"
                ctx.tags = [
                    "user.talon_hud_available", "user.talon_hud_visible",
                    "user.talon_hud_choices_visible"
                ]

            # Connect the events relating to non-content communication
            self.event_dispatch.register("persist_preferences",
                                         self.debounce_widget_preferences)
            self.event_dispatch.register("hide_context_menu",
                                         self.hide_context_menu)
            self.event_dispatch.register("deactivate_poller",
                                         self.deactivate_poller)
            self.event_dispatch.register("show_context_menu",
                                         self.move_context_menu)
            self.event_dispatch.register("synchronize_poller",
                                         self.synchronize_widget_poller)

            # Reload the preferences just in case a screen change happened in between the hidden state
            if persisted or self.current_flow in ["repair", "initialize"]:
                reload_theme = self.widget_manager.reload_preferences(
                    True, self.current_talon_hud_environment)
                if reload_theme != self.theme.name:
                    self.switch_theme(reload_theme, True)

            for widget in self.widget_manager.widgets:
                if widget.preferences.enabled and not widget.enabled:
                    widget.enable()
            self.synchronize_pollers()

            ui.register("screen_change", self.reload_preferences)
            settings.register("user.talon_hud_environment",
                              self.hud_environment_change)
            self.determine_active_setup_mouse()
            if persisted:
                self.preferences.persist_preferences({"enabled": True})
                self.set_current_flow("manual")

            # Make sure context isn't updated in this thread because of automatic reloads
            cron.cancel(self.update_context_debouncer)
            self.update_context_debouncer = cron.after("50ms",
                                                       self.update_context)
Exemplo n.º 27
0
    def load_state(self):
        if not os.path.exists(walkthrough_file_location):
            self.persist_walkthrough_steps(self.walkthrough_steps)

        fh = open(walkthrough_file_location, "r")
        lines = fh.readlines()
        fh.close()
        
        walkthrough_steps = {}
        for index,line in enumerate(lines):
            split_line = line.strip("\n").split(",")
            key = split_line[0]
            current_step = split_line[1]
            total_step = split_line[2]
            walkthrough_steps[key] = {"current": int(current_step), "total": int(total_step), "progress": int(current_step) / int(total_step) if int(total_step) > 0 else 0}
        self.walkthrough_steps = walkthrough_steps
        
        # For the initial loading, start the walkthrough if it hasn"t been completed fully yet
        if initial_walkthrough_title not in self.walkthrough_steps or \
            self.walkthrough_steps[initial_walkthrough_title]["current"] < self.walkthrough_steps[initial_walkthrough_title]["total"]:
            cron.after("1s", self.start_up_hud)
Exemplo n.º 28
0
def _on_hiss(start: bool):
    global _hiss_start_job
    if start:
        start_deadzone = settings["user.hiss_start_deadzone"]
        if start_deadzone:
            _hiss_start_job = cron.after(f"{start_deadzone}ms",
                                         _cued_start_hiss)
        else:
            actions.self.on_hiss(True)
    else:
        if _hiss_start_job:
            cron.cancel(_hiss_start_job)
        actions.self.on_hiss(False)
Exemplo n.º 29
0
 def on_noise(self, noise):
     pass
     now = time()
     # print(noise)
     if noise == 'pop':
         print('POP')
         if self.job:
             cron.cancel(self.job)
             self.job = None
             print('STOP')
         elif now - self.last_pop < 0.5 and self.job is not None:
             self.job = cron.after(self.initial_delay, self.repeat)
             print('START')
         self.last_pop = now
Exemplo n.º 30
0
def insert(s):
    global last_insert, reenable_job

    last_insert = s
    if eye_zoom_mouse.zoom_mouse.enabled:
        eye_zoom_mouse.zoom_mouse.toggle()
    if eye_mouse.control_mouse.enabled:
        eye_mouse.control_mouse.toggle()
        ctrl.cursor_visible(True)
        if reenable_job is None:
            reenable_job = cron.after("3s", enable_tracking)
    if reenable_job is not None:
        debounce_enable_job()
    Str(s)(None)