Skip to content

Commit

Permalink
Linux Fix and improvements
Browse files Browse the repository at this point in the history
Fix the deadlock issue caused by --sync (removed --sync since it is useless)
Fix the Chromebased since it needs focus before send input
Fix Firefox bug with xdotool since invisible window is returned by xdotool --visible-only
Add xdotool --desktop to search for compatibility purpose
Add dependency to wmctrl
Add Opera support
Add Chromium support
Add Midori support
Add QupZilla support
Add Konqueror support
Add Vivaldi support
Add custom window support for linux only
Add Firefox Nightly builds support (should be the same on mac, linux and windows)
  • Loading branch information
Kwaadpepper committed Oct 14, 2015
1 parent daee0ed commit fd50d66
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 23 deletions.
28 changes: 27 additions & 1 deletion BrowserRefresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,21 @@ def run(self, args, activate=True,
if 'chrome' in browsers:
refresher.chrome()

if 'chromium' in browsers and _os == 'Linux':
refresher.chromium()

if 'konqueror' in browsers and _os == 'Linux':
refresher.konqueror()

if 'midori' in browsers and _os == 'Linux':
refresher.midori()

if 'qupzilla' in browsers and _os == 'Linux':
refresher.qupzilla()

if 'vivaldi' in browsers and _os == 'Linux':
refresher.vivaldi()

if 'canary' in browsers and _os == 'Darwin':
refresher.canary()

Expand All @@ -65,6 +80,9 @@ def run(self, args, activate=True,
if 'firefox' in browsers:
refresher.firefox()

if 'nightly' in browsers and _os == 'Linux':
refresher.nightly()

if 'firefoxdev' in browsers and _os == 'Darwin':
refresher.firefox_dev()

Expand All @@ -77,5 +95,13 @@ def run(self, args, activate=True,
if 'iron' in browsers and _os == 'Windows':
refresher.iron()

if 'palemoon' in browsers and _os == 'Windows':
if 'palemoon' in browsers and _os in ['Windows', 'Linux']:
refresher.palemoon()

if _os == 'Linux':
for browser in browsers:
customWindow = browser.split(':')[1] if 'custom:' in browser else False
customCommand = customWindow.split(',')[1] if ',' in customWindow else False
customWindow = customWindow.split(',')[0] if ',' in customWindow else False
if customWindow:
refresher.custom(customWindow, customCommand)
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ git clone https://github.com/gcollazo/BrowserRefresh-Sublime.git "Browser Refres
Install xdotool:

```
sudo apt-get install xdotool
sudo apt-get install xdotool wmctrl
```

### 2. Configure Key Bindings
Expand Down Expand Up @@ -64,15 +64,28 @@ Specify which browsers to refresh on command. The default is `chrome` which will
|---------------------------|--------------|-----------------|
| Google Chrome | `chrome` | Mac, Win, Linux |
| Google Chrome Canary | `canary` | Mac, Win |
| Chromium | `chromium | Linux |
| Safari | `safari` | Mac, Win |
| WebKit | `webkit` | Mac |
| Firefox | `firefox` | Mac, Win, Linux |
| Firefox Developer Edition | `firefoxdev` | Mac |
| Opera | `opera` | Mac, Win |
| Firefox Nightly | `nightly` | Linux |
| Opera | `opera` | Mac, Win, Linux |
| Internet Explorer | `ie` | Win |
| SRWare Iron | `iron` | Win |
| Yandex | `yandex` | Mac |
| Pale Moon | `palemoon` | Win |
| Pale Moon | `palemoon` | Win,Linux |
| Konqueror | `konqueror` | Linux |
| Midori | `midori` | Linux |
| Qupzilla | `qupzilla` | Linux |
| Vivaldi | `vivaldi` | Linux |

**Linux special**

You can optionnally try to send any key on any window with a special browser argument
**"browsers" : ["custom:opera,ctrl+F5"]**

Keep in mind this is only for convenience purpose, it is absolutely not garranteed this method actually works

## Contributions
If you have the time to make this plugin better feel free to fork and submit a pull request.
Expand Down
144 changes: 125 additions & 19 deletions linux/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import sublime
from subprocess import call

from subprocess import call, Popen, PIPE, STDOUT

class LinuxBrowserRefresh:
def __init__(self, activate_browser):
# activate_browser is always true on Windows since you can't
# send keys to an inactive window programmatically. We ignore it.
self.activate_browser = activate_browser

def chrome(self):
self.SendKeysToAllWindows('google-chrome', 'F5')
# need to force ctrl+F5 here
self.SendKeyToAllWebkitBasedNavigators('google-chrome', 'ctrl+F5')

def chromium(self):
# need to force ctrl+F5 here
self.SendKeyToAllWebkitBasedNavigators('chromium-browser', 'ctrl+F5')

def konqueror(self):
# need to force ctrl+F5 here
self.SendKeyToAllWebkitBasedNavigators('konqueror', 'ctrl+F5')

def midori(self):
self.SendKeyToAllWindows('midori', 'F5')

def palemoon(self):
# need to force ctrl+F5 here
self.SendKeyToAllWindows('pale moon', 'F5')

def qupzilla(self):
# need to force ctrl+F5 here
self.SendKeyToAllWebkitBasedNavigators('qupzilla', 'ctrl+F5')

def iron(self):
pass
Expand All @@ -24,30 +41,119 @@ def safari64(self):
# except NotImplemented("Safari64 support not implemented yet.")

def firefox(self):
self.SendKeysToAllWindows('firefox', 'F5')
self.SendKeysToAllNamedWindows('firefox', 'F5')

def nightly(self):
self.SendKeysToAllNamedWindows('nightly', 'F5')

def vivaldi(self):
# need to force ctrl+F5 here
self.SendKeyToAllWebkitBasedNavigators('vivaldi', 'ctrl+F5')

def opera(self):
pass
# except NotImplemented("Opera support not implemented yet.")
# need to force ctrl+F5 here
self.SendKeyToAllWebkitBasedNavigators('opera', 'ctrl+F5')

def ie(self):
pass
# except NotImplemented("IE support not implemented yet.")

def SendKeysToAllWindows(self, cls, key):
"Sends the keystroke to all windows whose title matches the regex"
def custom(self, customWindow, customCommand):
customCommand = customCommand if customCommand else 'ctrl+R'
# Use the safer method
self.SendKeyToAllWebkitBasedNavigators(customWindow, customCommand)

def getDesktop(self):
'''This method is here for compatibilty purpose
because sometime xdotool would throw
XGetWindowProperty[_NET_WM_DESKTOP] failed (code=1)'''
cmd = ['xdotool', 'get_desktop']
try:
process = Popen(cmd, stdout=PIPE)
out, err = process.communicate()
return out.decode(encoding='UTF-8')
except Exception:
self.print_error(cmd)
return False

def SendKeyToAllWebkitBasedNavigators(self, cls, key):
cmd = ['xdotool', 'search',
'--desktop', self.getDesktop(),
'--onlyvisible',
'--class', cls,
'windowactivate', 'key', key]

cmd = ['xdotool', 'search', '--sync', '--onlyvisible', '--class', cls, 'windowfocus', 'key', key]
if self.activate_browser:
cmd += ['windowactivate']
else:
# trick to bring sublime text back to front
# this avoids the webkit bug where you have
# to activatewindow before inputing key
call(['subl'])

try:
call(cmd)
except Exception:
self.print_error(cmd)

def SendKeyToAllWindows(self, cls, key):
cmd = ['xdotool', 'search',
'--desktop', self.getDesktop(),
'--onlyvisible',
'--class', cls,
'key', key]

if self.activate_browser:
cmd += ['windowactivate']

status_code = call(cmd)
try:
call(cmd)
except Exception:
self.print_error(cmd)

def SendKeysToAllNamedWindows(self, cls, key):
"Sends the keystroke to all windows whose title matches the regex"

cmd = ['wmctrl', '-l']
try:
process = Popen(cmd, stdout=PIPE)
out, err = process.communicate()
except Exception:
self.print_error(cmd)
return

process = Popen(['grep', '-ie',
'[-]\?[a-z0-9 ]*%s[a-z0-9 ]*$' % cls],
stdout=PIPE, stdin=PIPE)
process.stdin.write(out)
out, err = process.communicate()

wID = ""
try:
wID = out.split()[0].decode(encoding='UTF-8')
except Exception:
# no window found
return

cmd = ['xdotool', 'key', '--window', wID, key]
try:
call(cmd)
except Exception:
self.print_error(cmd)
return

if self.activate_browser:
cmd = ['xdotool', 'windowactivate', wID]
try:
call(cmd)
except Exception:
self.print_error(cmd)
return

if status_code != 0:
sublime.error_message(
'Browser Refresh cannot execute the specified program.\n\n'
'%s\n\n'
'If program \'xdotool\' is currently not installed '
'you can install it by typing:\n\n'
'sudo apt-get install xdotool' % " ".join(cmd))
def print_error(prog, cmd):
sublime.error_message(
'Browser Refresh cannot execute the specified program.\n\n'
'%s\n\n'
'If program \'%s\' is currently not installed '
'you can install it by typing:\n\n'
'sudo apt-get install %s' % (' '.join(cmd), cmd[0], cmd[0]))

0 comments on commit fd50d66

Please sign in to comment.