Skip to content
This repository was archived by the owner on May 6, 2020. It is now read-only.

remove lag from window changes #28

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions dragonfly/engines/base/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ def load_grammar(self, grammar):
wrapper = self._load_grammar(grammar)
self._grammar_wrappers[wrapper_key] = wrapper

def window_change(self, executable, title, handle):
for wrapper in self._grammar_wrappers.values():
wrapper.grammar.window_change(executable, title, handle)

def _load_grammar(self, grammar):
raise NotImplementedError("Virtual method not implemented for"
" engine %s." % self)
Expand Down
25 changes: 24 additions & 1 deletion dragonfly/examples/dfly-loader-wsr.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@
directory it's in and loads any ``*.py`` it finds.

"""

import ctypes
import ctypes.wintypes

import time
import os.path
import logging
import pythoncom
import win32con
from dragonfly import Window

from dragonfly.engines.backend_sapi5.engine import Sapi5InProcEngine

Expand Down Expand Up @@ -139,6 +142,26 @@ def main():
directory = CommandModuleDirectory(path, excludes=[__file__])
directory.load()

WinEventProcType = ctypes.WINFUNCTYPE(None, ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.HWND,
ctypes.wintypes.LONG, ctypes.wintypes.LONG, ctypes.wintypes.DWORD,
ctypes.wintypes.DWORD)

def callback(hWinEventHook, event, hwnd, idObject, idChild, dwEventThread, dwmsEventTime):
window = Window.get_foreground()
if hwnd == window.handle:
engine.window_change(window.executable, window.title, window.handle)


def set_hook(win_event_proc, event_type):
return ctypes.windll.user32.SetWinEventHook(event_type, event_type, 0, win_event_proc, 0, 0, win32con.WINEVENT_OUTOFCONTEXT)


win_event_proc = WinEventProcType(callback)
ctypes.windll.user32.SetWinEventHook.restype = ctypes.wintypes.HANDLE

[set_hook(win_event_proc, et) for et in
{win32con.EVENT_SYSTEM_FOREGROUND, win32con.EVENT_OBJECT_NAMECHANGE, }]

engine.speak('beginning loop!')
while 1:
pythoncom.PumpWaitingMessages()
Expand Down
39 changes: 38 additions & 1 deletion dragonfly/grammar/grammar_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# (c) Copyright 2007, 2008 by Christo Butcher
# Licensed under the LGPL.
#
# Dragonfly is free software: you can redistribute it and/or modify it
# Dragonfly is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
Expand Down Expand Up @@ -427,6 +427,43 @@ def process_begin(self, executable, title, handle):
self._log_begin.debug("Grammar %s: active rules: %s."
% (self._name, [r.name for r in self._rules if r.active]))

def window_change(self, executable, title, handle):
"""
Foreground window changed detected

This method is called when the foreground window changes or the title of the foreground window changes.

Arguments:
- *executable* -- the full path to the module whose window is currently in the foreground.
- *title* -- window title of the foreground window.
- *handle* -- window handle to the foreground window.

"""
self._log_begin.debug("Grammar %s: detected window change." % self._name)
self._log_begin.debug("Grammar %s: executable '%s', title '%s'." % (self._name, executable, title))

if not self._enabled:
# Grammar is disabled, so deactivate all active rules.
[r.deactivate() for r in self._rules if r.active]

elif not self._context or self._context.matches(executable, title, handle):
# Grammar is within context.
if not self._in_context:
self._in_context = True
self.enter_context()
for r in self._rules:
r.activate()

else:
# Grammar's context doesn't match, deactivate active rules.
if self._in_context:
self._in_context = False
self.exit_context()
[r.deactivate() for r in self._rules if r.active]

self._log_begin.debug("Grammar %s: active rules: %s."
% (self._name, [r.name for r in self._rules if r.active]))

def enter_context(self):
"""
Enter context callback.
Expand Down