Merge pull request #4 from MaskRay/whitespace

Remove trailing whitespace
master
Andy Stewart 8 years ago committed by GitHub
commit 20c34dda5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      app/browser/buffer.py
  2. 50
      app/imageviewer/buffer.py
  3. 20
      app/videoplayer/buffer.py
  4. 42
      core/buffer.py
  5. 102
      core/eaf.py
  6. 2
      core/fake_key_event.py
  7. 56
      core/view.py
  8. 16
      core/xutils.py

@ -2,20 +2,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -27,15 +27,15 @@ from buffer import Buffer
class BrowserBuffer(Buffer):
def __init__(self, buffer_id, url, width, height):
Buffer.__init__(self, buffer_id, url, width, height, QColor(255, 255, 255, 255))
self.buffer_widget = QWebView()
self.buffer_widget.resize(self.width, self.height)
self.buffer_widget.setUrl(QUrl(url))
print("Create buffer: %s" % buffer_id)
def resize_buffer(self, width, height):
self.width = width
self.height = height
self.buffer_widget.resize(self.width, self.height)

@ -2,20 +2,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -28,10 +28,10 @@ from buffer import Buffer
class ImageViewerBuffer(Buffer):
def __init__(self, buffer_id, url, width, height):
Buffer.__init__(self, buffer_id, url, width, height, QColor(0, 0, 0, 255))
self.buffer_widget = ImageViewerWidget(url, QColor(0, 0, 0, 255))
self.buffer_widget.resize(self.width, self.height)
def resize_buffer(self, width, height):
self.width = width
self.height = height
@ -40,16 +40,16 @@ class ImageViewerBuffer(Buffer):
class ImageViewerWidget(QWidget):
def __init__(self, image_path, background_color):
QWidget.__init__(self)
self.background_color = background_color
self.load_image(image_path)
def load_image(self, image_path):
self.parent_dir = os.path.abspath(os.path.join(image_path, os.pardir))
self.image_name = os.path.basename(image_path)
self.qimage = QPixmap(image_path)
self.update()
def load_next_image(self):
files = [f for f in os.listdir(self.parent_dir) if os.path.isfile(os.path.join(self.parent_dir, f))]
images = list(filter(lambda f: f.endswith(".jpg") or f.endswith(".png"), files))
@ -59,9 +59,9 @@ class ImageViewerWidget(QWidget):
image_index = 0
else:
image_index += 1
self.load_image(os.path.join(self.parent_dir, images[image_index]))
self.load_image(os.path.join(self.parent_dir, images[image_index]))
def load_prev_image(self):
files = [f for f in os.listdir(self.parent_dir) if os.path.isfile(os.path.join(self.parent_dir, f))]
images = list(filter(lambda f: f.endswith(".jpg") or f.endswith(".png"), files))
@ -71,15 +71,15 @@ class ImageViewerWidget(QWidget):
image_index = len(images) - 1
else:
image_index -= 1
self.load_image(os.path.join(self.parent_dir, images[image_index]))
self.load_image(os.path.join(self.parent_dir, images[image_index]))
def paintEvent(self, event):
painter = QPainter(self)
painter.setBrush(self.background_color)
painter.drawRect(0, 0, self.rect().width(), self.rect().height())
width_scale = self.rect().width() * 1.0 / self.qimage.width()
height_scale = self.rect().height() * 1.0 / self.qimage.height()
image_scale = 1.0
@ -87,31 +87,31 @@ class ImageViewerWidget(QWidget):
image_scale = width_scale
else:
image_scale = height_scale
render_width = image_scale * self.qimage.width()
render_height = image_scale * self.qimage.height()
render_width = image_scale * self.qimage.width()
render_height = image_scale * self.qimage.height()
render_x = (self.rect().width() - render_width) / 2
render_y = (self.rect().height() - render_height) / 2
painter.drawPixmap(QRect(render_x, render_y, render_width, render_height), self.qimage)
painter.end()
def keyPressEvent(self, event):
if event.key() == Qt.Key_J:
self.load_next_image()
elif event.key() == Qt.Key_K:
self.load_prev_image()
if __name__ == "__main__":
from PyQt5.QtWidgets import QApplication
import sys
import signal
app = QApplication(sys.argv)
test = ImageViewerWidget("/home/andy/rms/1.jpg", QColor(0, 0, 0, 255))
test.show()
signal.signal(signal.SIGINT, signal.SIG_DFL)
sys.exit(app.exec_())

@ -2,20 +2,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -34,19 +34,19 @@ html_file = '''
margin: 0px;
padding: 0px;
}
body {
margin: 0px;
padding: 0px;
}
video {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
::-webkit-scrollbar {
display: none;
}
@ -59,13 +59,13 @@ html_file = '''
class VideoPlayerBuffer(Buffer):
def __init__(self, buffer_id, url, width, height):
Buffer.__init__(self, buffer_id, url, width, height, QColor(255, 255, 255, 255))
self.buffer_widget = QWebView()
self.buffer_widget.resize(self.width, self.height)
self.buffer_widget.setHtml(html_file.replace("**********", url))
print("Create buffer: %s" % buffer_id)
def resize_buffer(self, width, height):
self.width = width
self.height = height

@ -2,20 +2,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -25,59 +25,59 @@ import functools
import abc
class postGui(QtCore.QObject):
through_thread = QtCore.pyqtSignal(object, object)
through_thread = QtCore.pyqtSignal(object, object)
def __init__(self, inclass=True):
super(postGui, self).__init__()
self.through_thread.connect(self.on_signal_received)
self.inclass = inclass
def __call__(self, func):
self._func = func
@functools.wraps(func)
def obj_call(*args, **kwargs):
self.emit_signal(args, kwargs)
return obj_call
def emit_signal(self, args, kwargs):
self.through_thread.emit(args, kwargs)
def on_signal_received(self, args, kwargs):
if self.inclass:
obj, args = args[0], args[1:]
self._func(obj, *args, **kwargs)
else:
else:
self._func(*args, **kwargs)
class Buffer(object):
__metaclass__ = abc.ABCMeta
def __init__(self, buffer_id, url, width, height, background_color):
self.width = width
self.height = height
self.buffer_id = buffer_id
self.url = url
self.qimage = None
self.buffer_widget = None
self.background_color = background_color
def resize_buffer(self, width, height):
pass
def handle_destroy(self):
if self.buffer_widget != None:
self.buffer_widget.destroy()
if self.qimage != None:
del self.qimage
print("Destroy buffer: %s" % self.buffer_id)
@postGui()
@postGui()
def update_content(self):
if self.buffer_widget != None:
qimage = QImage(self.width, self.height, QImage.Format_ARGB32)

@ -2,20 +2,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -33,7 +33,7 @@ import time
import os,sys,inspect
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parent_dir = os.path.dirname(current_dir)
sys.path.insert(0, parent_dir)
sys.path.insert(0, parent_dir)
from app.browser.buffer import BrowserBuffer
from app.imageviewer.buffer import ImageViewerBuffer
from app.videoplayer.buffer import VideoPlayerBuffer
@ -44,18 +44,18 @@ EAF_OBJECT_NAME = "/com/lazycat/eaf"
class EAF(dbus.service.Object):
def __init__(self, args):
global emacs_xid, emacs_width, emacs_height
dbus.service.Object.__init__(
self,
dbus.service.BusName(EAF_DBUS_NAME, bus=dbus.SessionBus()),
EAF_OBJECT_NAME)
(emacs_xid, emacs_width, emacs_height) = (map(lambda x: int(x), args))
self.buffer_dict = {}
self.view_dict = {}
self.start_finish()
@dbus.service.method(EAF_DBUS_NAME, in_signature="ss", out_signature="s")
def new_buffer(self, buffer_id, url):
global emacs_width, emacs_height
@ -68,7 +68,7 @@ class EAF(dbus.service.Object):
else:
return "Don't know how to open {0}".format(url)
else:
from urllib.parse import urlparse
from urllib.parse import urlparse
result = urlparse(url)
if len(result.scheme) != 0:
self.buffer_dict[buffer_id] = BrowserBuffer(buffer_id, result.geturl(), emacs_width, emacs_height)
@ -78,31 +78,31 @@ class EAF(dbus.service.Object):
self.buffer_dict[buffer_id] = BrowserBuffer(buffer_id, result.geturl(), emacs_width, emacs_height)
else:
return "{0} is not valid url".format(url)
return ""
@dbus.service.method(EAF_DBUS_NAME, in_signature="s", out_signature="")
def update_views(self, args):
global emacs_xid
view_infos = args.split(",")
# Remove old key from view dict and destroy old view.
for key in list(self.view_dict):
if key not in view_infos:
self.view_dict[key].handle_destroy()
self.view_dict.pop(key, None)
# Create new view and udpate in view dict.
if view_infos != ['']:
for view_info in view_infos:
if view_info not in self.view_dict:
view = View(emacs_xid, view_info)
self.view_dict[view_info] = view
view.trigger_mouse_event.connect(self.send_mouse_event_to_buffer)
view.trigger_focus_event.connect(self.focus_emacs_buffer)
@dbus.service.method(EAF_DBUS_NAME, in_signature="s", out_signature="")
def kill_buffer(self, buffer_id):
# Kill all view base on buffer_id.
@ -110,51 +110,51 @@ class EAF(dbus.service.Object):
if buffer_id == self.view_dict[key].buffer_id:
self.view_dict[key].handle_destroy()
self.view_dict.pop(key, None)
# Clean buffer from buffer dict.
if buffer_id in self.buffer_dict:
self.buffer_dict[buffer_id].handle_destroy()
self.buffer_dict.pop(buffer_id, None)
@dbus.service.method(EAF_DBUS_NAME, in_signature="s", out_signature="")
def send_key(self, args):
print("Send key: %s" % args)
(buffer_id, event_string) = args.split(":")
if buffer_id in self.buffer_dict:
QApplication.sendEvent(self.buffer_dict[buffer_id].buffer_widget, fake_key_event(event_string))
@dbus.service.signal("com.lazycat.eaf")
@dbus.service.signal("com.lazycat.eaf")
def focus_emacs_buffer(self, message):
print("************* %s" % message)
@dbus.service.signal("com.lazycat.eaf")
@dbus.service.signal("com.lazycat.eaf")
def start_finish(self):
pass
def send_mouse_event_to_buffer(self, buffer_id, view_width, view_height, view_image_width, view_image_height, event):
print("Send mouse: %s %s" % (buffer_id, event))
global emacs_xid
if buffer_id in self.buffer_dict:
if event.type() in [QEvent.MouseButtonPress, QEvent.MouseButtonRelease,
QEvent.MouseMove, QEvent.MouseButtonDblClick]:
# Get view render coordinate.
view_render_x = (view_width - view_image_width) / 2
view_render_y = (view_height - view_image_height) / 2
# Just send event if response in view image area.
if (event.x() >= view_render_x) and (event.x() <= view_render_x + view_image_width) and (event.y() >= view_render_y) and (event.y() <= view_render_y + view_image_height):
view_sizes = list(map(lambda v: (v.width, v.height), self.view_dict.values()))
buffer_width = emacs_width
buffer_height = emacs_height
if len(view_sizes) > 0:
buffer_width, buffer_height = max(view_sizes, key=lambda size: size[0] * size[1])
width_scale = view_width * 1.0 / buffer_width
height_scale = view_height * 1.0 / buffer_height
image_scale = 1.0
@ -166,42 +166,42 @@ class EAF(dbus.service.Object):
new_event_x = (event.x() - view_render_x) / image_scale
new_event_y = (event.y() - view_render_y) / image_scale
new_event_pos = QPointF(new_event_x, new_event_y)
new_event = QMouseEvent(event.type(),
new_event_pos,
event.button(),
event.buttons(),
event.modifiers())
QApplication.sendEvent(self.buffer_dict[buffer_id].buffer_widget, new_event)
else:
print("Do not send event, because event out of view's response area")
else:
QApplication.sendEvent(self.buffer_dict[buffer_id].buffer_widget, event)
def update_buffers(self):
global emacs_width, emacs_height
while True:
for buffer in list(self.buffer_dict.values()):
# Get size list of buffer's views.
view_sizes = list(map(lambda v: (v.width, v.height), self.view_dict.values()))
# Init buffer size with emacs' size.
buffer_width = emacs_width
buffer_height = emacs_height
# Update buffer size with max area view's size,
# to make each view has the same rendering area after user do split operation in emacs.
if len(view_sizes) > 0:
buffer_width, buffer_height = max(view_sizes, key=lambda size: size[0] * size[1])
# Resize buffer.
buffer.resize_buffer(buffer_width, buffer_height)
buffer.resize_buffer(buffer_width, buffer_height)
# Update buffer image.
buffer.update_content()
if buffer.qimage != None:
# Render views.
for view in list(self.view_dict.values()):
@ -220,29 +220,29 @@ class EAF(dbus.service.Object):
# Update view.
view.update()
time.sleep(0.04)
if __name__ == "__main__":
import sys
import signal
DBusGMainLoop(set_as_default=True) # WARING: only use once in one process
bus = dbus.SessionBus()
if bus.request_name(EAF_DBUS_NAME) != dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER:
print("EAF process has startup.")
else:
emacs_xid = 0
emacs_width = emacs_height = 0
app = QApplication(sys.argv)
eaf = EAF(sys.argv[1:])
threading.Thread(target=eaf.update_buffers).start()
print("EAF process start.")
signal.signal(signal.SIGINT, signal.SIG_DFL)
sys.exit(app.exec_())

@ -82,5 +82,5 @@ def fake_key_event(event_string):
text = event_string
if event_string in qt_text_dict:
text = qt_text_dict[event_string]
return QKeyEvent(QEvent.KeyPress, qt_key_dict[event_string], Qt.NoModifier, text)

@ -2,20 +2,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Andy Stewart
#
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -26,20 +26,20 @@ from PyQt5.QtWidgets import QWidget
from xutils import get_xlib_display
class View(QWidget):
trigger_mouse_event = QtCore.pyqtSignal(str, int, int, int, int, QEvent)
trigger_focus_event = QtCore.pyqtSignal(str)
def __init__(self, emacs_xid, view_info):
super(View, self).__init__()
self.emacs_xid = emacs_xid
# Init widget attributes.
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_X11DoNotAcceptFocus, True)
self.setContentsMargins(0, 0, 0, 0)
# Init attributes.
self.view_info = view_info
(self.buffer_id, self.x, self.y, self.width, self.height) = view_info.split(":")
@ -47,65 +47,65 @@ class View(QWidget):
self.y = int(self.y)
self.width = int(self.width)
self.height = int(self.height)
self.qimage = None
self.background_color = None
# Show and resize.
self.show()
self.resize(self.width, self.height)
self.installEventFilter(self)
print("Create view: %s" % self.view_info)
def eventFilter(self, obj, event):
if event.type() in [QEvent.MouseButtonPress, QEvent.MouseButtonRelease,
QEvent.MouseMove, QEvent.MouseButtonDblClick, QEvent.Wheel]:
self.trigger_mouse_event.emit(self.buffer_id, self.width, self.height, self.qimage.width(), self.qimage.height(), event)
self.trigger_focus_event.emit("{0},{1}".format(event.globalX(), event.globalY()))
return False
def paintEvent(self, event):
# Init painter.
painter = QPainter(self)
# Render background.
if self.background_color != None:
painter.setBrush(self.background_color)
painter.drawRect(0, 0, self.width, self.height)
# Render buffer image in center of view.
if self.qimage != None:
render_x = (self.width - self.qimage.width()) / 2
render_y = (self.height - self.qimage.height()) / 2
painter.drawImage(QtCore.QRect(render_x, render_y, self.qimage.width(), self.qimage.height()), self.qimage)
# End painter.
painter.end()
def showEvent(self, event):
# NOTE: we must reparent after widget show, otherwise reparent operation maybe failed.
self.reparent()
def reparent(self):
xlib_display = get_xlib_display()
view_xid = self.winId().__int__()
view_xwindow = xlib_display.create_resource_object("window", view_xid)
emacs_xwindow = xlib_display.create_resource_object("window", self.emacs_xid)
view_xwindow.reparent(emacs_xwindow, self.x, self.y)
xlib_display.sync()
def handle_destroy(self):
if self.qimage != None:
del self.qimage
self.destroy()
print("Destroy view: %s" % self.view_info)

@ -2,20 +2,20 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2011 ~ 2014 Andy Stewart
#
#
# Author: Andy Stewart <lazycat.manatee@gmail.com>
# Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
@ -23,12 +23,12 @@ xlib_display = None
def get_xlib_display():
global xlib_display
if xlib_display == None:
from Xlib import display
xlib_display = display.Display()
return xlib_display
return xlib_display
def grab_focus(window_id):
global xlib_display
@ -38,7 +38,7 @@ def grab_focus(window_id):
xwindow.set_input_focus(X.RevertToNone, X.CurrentTime)
xwindow.configure(stack_mode=X.Above)
xlib_display.sync()
def get_parent_window_id(window_id):

Loading…
Cancel
Save