You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.7 KiB
111 lines
3.7 KiB
#!/usr/bin/env python |
|
# -*- 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/>. |
|
|
|
from PyQt5 import QtCore |
|
from PyQt5.QtCore import Qt, QEvent |
|
from PyQt5.QtGui import QPainter |
|
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(":") |
|
self.x = int(self.x) |
|
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) |
|
|
|
|
|
|