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

Linux Bug fix and improvements #84

Closed
wants to merge 1 commit into from
Closed
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
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]))