Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support focusing windows without raising them on X11 #193

Merged
merged 2 commits into from
Jan 11, 2020
Merged
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
17 changes: 14 additions & 3 deletions dragonfly/actions/action_focuswindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,27 +47,33 @@ class FocusWindow(ActionBase):
(the window object), and should return ``True`` for your
target windows; example:
``lambda window: window.get_position().dy > 100``.
- *focus_only* (*bool*, default *False*) -- if *True*, then
attempt to focus the window without raising it by using the
*Window.set_focus()* method instead of *set_foreground()*.
This argument may do nothing depending on the platform.
This action searches all visible windows for a window which
matches the given parameters.
"""

def __init__(self, executable=None, title=None, index=None,
filter_func=None):
filter_func=None, focus_only=False):
if executable: self.executable = executable.lower()
else: self.executable = None
if title: self.title = title.lower()
else: self.title = None
self.index = index
self.filter_func = filter_func
self.focus_only = focus_only
ActionBase.__init__(self)

arguments = []
if executable: arguments.append("executable=%r" % executable)
if title: arguments.append("title=%r" % title)
if index: arguments.append("index=%r" % index)
if filter_func: arguments.append("filter_func=%r" % filter_func)
if focus_only: arguments.append("focus_only=%r" % focus_only)
self._str = ", ".join(arguments)

def _execute(self, data=None):
Expand All @@ -84,8 +90,13 @@ def _execute(self, data=None):
# Get the first matching window and bring it to the foreground.
windows = Window.get_matching_windows(executable, title)
if self.filter_func:
windows = [window for window in windows if self.filter_func(window)]
windows = [window for window in windows
if self.filter_func(window)]
if windows and (index < len(windows)):
windows[index].set_foreground()
window = windows[index]
if self.focus_only:
window.set_focus()
else:
window.set_foreground()
else:
raise ActionError("Failed to find window (%s)." % self._str)
9 changes: 8 additions & 1 deletion dragonfly/actions/action_startapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,16 @@ def __init__(self, *args, **kwargs):
if *True*, then attempt to bring the window to the foreground
after starting the application. Does nothing if the
application is already running.
- *focus_only* (*bool*, default *False*) -- if *True*, then
attempt to focus a matching window without raising it by
using the *set_focus()* method instead of *set_foreground()*.
This argument may do nothing depending on the platform.
"""
self._title = kwargs.pop("title", None)
self._index = kwargs.pop("index", None)
self._filter_func = kwargs.pop("filter_func", None)
self._focus_only = kwargs.pop("focus_only", False)
StartApp.__init__(self, *args, **kwargs)

def _execute(self, data=None):
Expand All @@ -203,8 +208,10 @@ def _execute(self, data=None):
title = self._title
index = self._index
filter_func = self._filter_func
focus_only = self._focus_only
focus_action = FocusWindow(executable=target, title=title,
index=index, filter_func=filter_func)
index=index, filter_func=filter_func,
focus_only=focus_only)
# Attempt to focus on an existing window.
if not focus_action.execute():
# Failed to focus on an existing window, so start
Expand Down
9 changes: 9 additions & 0 deletions dragonfly/windows/base_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,15 @@ def set_foreground(self):
""" Set the window as the foreground (active) window. """
raise NotImplementedError()

def set_focus(self):
"""
Set the window as the active window without raising it.
*Note*: this method will behave like :meth:`set_foreground()` in
environments where this isn't possible.
"""
raise NotImplementedError()

def move(self, rectangle, animate=None):
"""
Move the window, optionally animating its movement.
Expand Down
5 changes: 5 additions & 0 deletions dragonfly/windows/darwin_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,8 @@ def set_foreground(self):
end tell
''' % self._id
applescript.AppleScript(script).run()

def set_focus(self):
# Setting window focus without raising the window doesn't appear to
# be possible in macOS, so fallback on set_foreground().
self.set_foreground()
3 changes: 3 additions & 0 deletions dragonfly/windows/fake_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,6 @@ def close(self):

def set_foreground(self):
pass

def set_focus(self):
pass
5 changes: 5 additions & 0 deletions dragonfly/windows/win32_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,8 @@ def set_foreground(self):

# Set the foreground window.
self._set_foreground()

def set_focus(self):
# Setting window focus without raising the window doesn't appear to
# be possible in Windows, so fallback on set_foreground().
self.set_foreground()