Skip to content

Commit c3ab6a6

Browse files
Port to PyQt6
1 parent 98ebfb9 commit c3ab6a6

File tree

8 files changed

+165
-161
lines changed

8 files changed

+165
-161
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Unfortunately, this 45 years of age is also one of the greatest disadvantages of
1717

1818
Emacs, although infinitely extensible in text, is very limited in graphics. It shouldn't have to be this way. However, Emacs Lisp is *the* integral part of the Emacs culture, it carries decades of history with itself, it is what makes Emacs special. It is irreplaceable.
1919

20-
The vision of the Emacs Application Framework (EAF) project is, while fully retaining the rich history, culture, and ecosystem of Emacs and Emacs Lisp, to open up completely new doors to the ecosystems of Python, Qt5, and even JavaScript. EAF extends Emacs to the world of modern graphics, but still preserving the extensibility and customizability of Emacs. It will be the key to ultimately *Live in Emacs*.
20+
The vision of the Emacs Application Framework (EAF) project is, while fully retaining the rich history, culture, and ecosystem of Emacs and Emacs Lisp, to open up completely new doors to the ecosystems of Python, Qt6, and even JavaScript. EAF extends Emacs to the world of modern graphics, but still preserving the extensibility and customizability of Emacs. It will be the key to ultimately *Live in Emacs*.
2121

2222

2323
## Features

core/buffer.py

Lines changed: 68 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
# You should have received a copy of the GNU General Public License
2020
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2121

22-
from PyQt5.QtCore import Qt, QEvent, QThread, pyqtSignal
23-
from PyQt5.QtGui import QKeyEvent, QCursor, QFocusEvent, QColor
24-
from PyQt5.QtWidgets import QGraphicsScene, QApplication, qApp
22+
from PyQt6.QtCore import Qt, QEvent, QThread, pyqtSignal
23+
from PyQt6.QtGui import QKeyEvent, QCursor, QFocusEvent, QColor
24+
from PyQt6.QtWidgets import QGraphicsScene, QApplication
2525
from core.utils import (interactive, abstract, get_clipboard_text,
2626
set_clipboard_text, eval_in_emacs, message_to_emacs,
2727
input_message, get_emacs_var, get_emacs_func_result,
@@ -34,63 +34,63 @@
3434
# Build char event.
3535
for char in string.ascii_lowercase:
3636
upper_char = char.upper()
37-
qt_key_dict[char] = eval("Qt.Key_{}".format(upper_char))
38-
qt_key_dict[upper_char] = eval("Qt.Key_{}".format(upper_char))
37+
qt_key_dict[char] = eval("Qt.Key.Key_{}".format(upper_char))
38+
qt_key_dict[upper_char] = eval("Qt.Key.Key_{}".format(upper_char))
3939

4040
# Build number event.
4141
for number in range(0, 10):
42-
qt_key_dict[str(number)] = eval("Qt.Key_{}".format(number))
42+
qt_key_dict[str(number)] = eval("Qt.Key.Key_{}".format(number))
4343

4444
qt_key_dict.update({
45-
''':''': Qt.Key_Colon,
46-
''';''': Qt.Key_Semicolon,
47-
'''.''': Qt.Key_Period,
48-
''',''': Qt.Key_Comma,
49-
'''+''': Qt.Key_Plus,
50-
'''-''': Qt.Key_Minus,
51-
'''=''': Qt.Key_Equal,
52-
'''_''': Qt.Key_Underscore,
53-
'''[''': Qt.Key_BracketLeft,
54-
''']''': Qt.Key_BracketRight,
55-
'''(''': Qt.Key_BraceLeft,
56-
''')''': Qt.Key_BraceRight,
57-
'''{''': Qt.Key_ParenLeft,
58-
'''}''': Qt.Key_ParenRight,
59-
'''<''': Qt.Key_Less,
60-
'''>''': Qt.Key_Greater,
61-
'''@''': Qt.Key_At,
62-
'''\\''': Qt.Key_Backslash,
63-
'''|''': Qt.Key_Bar,
64-
'''/''': Qt.Key_Slash,
65-
'''#''': Qt.Key_NumberSign,
66-
'''$''': Qt.Key_Dollar,
67-
'''?''': Qt.Key_Question,
68-
'''"''': Qt.Key_QuoteDbl,
69-
'''`''': Qt.Key_QuoteLeft,
70-
'''%''': Qt.Key_Percent,
71-
'''^''': Qt.Key_AsciiCircum,
72-
'''&''': Qt.Key_Ampersand,
73-
'''*''': Qt.Key_Asterisk,
74-
'''~''': Qt.Key_AsciiTilde,
75-
'''!''': Qt.Key_Exclam,
76-
'''\'''': Qt.Key_Apostrophe,
77-
'''SPC''': Qt.Key_Space,
78-
'''RET''': Qt.Key_Return,
79-
'''DEL''': Qt.Key_Backspace,
80-
'''TAB''': Qt.Key_Tab,
81-
'''<backtab>''': Qt.Key_Backtab,
82-
'''<home>''': Qt.Key_Home,
83-
'''<end>''': Qt.Key_End,
84-
'''<left>''': Qt.Key_Left,
85-
'''<right>''': Qt.Key_Right,
86-
'''<up>''': Qt.Key_Up,
87-
'''<down>''': Qt.Key_Down,
88-
'''<prior>''': Qt.Key_PageUp,
89-
'''<next>''': Qt.Key_PageDown,
90-
'''<delete>''': Qt.Key_Delete,
91-
'''<backspace>''': Qt.Key_Backspace,
92-
'''<return>''': Qt.Key_Return,
93-
'''<escape>''': Qt.Key_Escape
45+
''':''': Qt.Key.Key_Colon,
46+
''';''': Qt.Key.Key_Semicolon,
47+
'''.''': Qt.Key.Key_Period,
48+
''',''': Qt.Key.Key_Comma,
49+
'''+''': Qt.Key.Key_Plus,
50+
'''-''': Qt.Key.Key_Minus,
51+
'''=''': Qt.Key.Key_Equal,
52+
'''_''': Qt.Key.Key_Underscore,
53+
'''[''': Qt.Key.Key_BracketLeft,
54+
''']''': Qt.Key.Key_BracketRight,
55+
'''(''': Qt.Key.Key_BraceLeft,
56+
''')''': Qt.Key.Key_BraceRight,
57+
'''{''': Qt.Key.Key_ParenLeft,
58+
'''}''': Qt.Key.Key_ParenRight,
59+
'''<''': Qt.Key.Key_Less,
60+
'''>''': Qt.Key.Key_Greater,
61+
'''@''': Qt.Key.Key_At,
62+
'''\\''': Qt.Key.Key_Backslash,
63+
'''|''': Qt.Key.Key_Bar,
64+
'''/''': Qt.Key.Key_Slash,
65+
'''#''': Qt.Key.Key_NumberSign,
66+
'''$''': Qt.Key.Key_Dollar,
67+
'''?''': Qt.Key.Key_Question,
68+
'''"''': Qt.Key.Key_QuoteDbl,
69+
'''`''': Qt.Key.Key_QuoteLeft,
70+
'''%''': Qt.Key.Key_Percent,
71+
'''^''': Qt.Key.Key_AsciiCircum,
72+
'''&''': Qt.Key.Key_Ampersand,
73+
'''*''': Qt.Key.Key_Asterisk,
74+
'''~''': Qt.Key.Key_AsciiTilde,
75+
'''!''': Qt.Key.Key_Exclam,
76+
'''\'''': Qt.Key.Key_Apostrophe,
77+
'''SPC''': Qt.Key.Key_Space,
78+
'''RET''': Qt.Key.Key_Return,
79+
'''DEL''': Qt.Key.Key_Backspace,
80+
'''TAB''': Qt.Key.Key_Tab,
81+
'''<backtab>''': Qt.Key.Key_Backtab,
82+
'''<home>''': Qt.Key.Key_Home,
83+
'''<end>''': Qt.Key.Key_End,
84+
'''<left>''': Qt.Key.Key_Left,
85+
'''<right>''': Qt.Key.Key_Right,
86+
'''<up>''': Qt.Key.Key_Up,
87+
'''<down>''': Qt.Key.Key_Down,
88+
'''<prior>''': Qt.Key.Key_PageUp,
89+
'''<next>''': Qt.Key.Key_PageDown,
90+
'''<delete>''': Qt.Key.Key_Delete,
91+
'''<backspace>''': Qt.Key.Key_Backspace,
92+
'''<return>''': Qt.Key.Key_Return,
93+
'''<escape>''': Qt.Key.Key_Escape
9494
})
9595

9696
qt_text_dict = {
@@ -183,7 +183,7 @@ def move_cursor_to_corner(self):
183183
'''
184184
Move cursor to bottom right corner of screen.
185185
'''
186-
screen = qApp.primaryScreen()
186+
screen = QApplication.instance().primaryScreen()
187187
try:
188188
QCursor().setPos(screen, screen.size().width(), screen.size().height())
189189
except:
@@ -359,7 +359,7 @@ def send_key(self, event_string):
359359
''' Fake key event.'''
360360
# Init.
361361
text = event_string
362-
modifier = Qt.NoModifier
362+
modifier = Qt.KeyboardModifier.NoModifier
363363

364364
# Get key text.
365365
if event_string in qt_text_dict:
@@ -368,17 +368,17 @@ def send_key(self, event_string):
368368
if event_string in ["TAB", "<backtab>"]:
369369
text = ""
370370
if event_string == "<backtab>":
371-
modifier = Qt.ShiftModifier
371+
modifier = Qt.KeyboardModifier.ShiftModifier
372372
elif event_string.isupper():
373-
modifier = Qt.ShiftModifier
373+
modifier = Qt.KeyboardModifier.ShiftModifier
374374

375375
# print("Press: ", event_string)
376376

377377
# NOTE: don't ignore text argument, otherwise QWebEngineView not respond key event.
378378
try:
379-
key_press = QKeyEvent(QEvent.KeyPress, qt_key_dict[event_string], modifier, text)
379+
key_press = QKeyEvent(QEvent.Type.KeyPress, qt_key_dict[event_string], modifier, text)
380380
except:
381-
key_press = QKeyEvent(QEvent.KeyPress, Qt.Key_unknown, modifier, text)
381+
key_press = QKeyEvent(QEvent.Type.KeyPress, Qt.Key.Key_unknown, modifier, text)
382382

383383
for widget in self.get_key_event_widgets():
384384
QApplication.sendEvent(widget, key_press)
@@ -396,19 +396,19 @@ def send_key_sequence(self, event_string):
396396
if len(last_char) == 1:
397397
last_key = last_char.lower()
398398

399-
modifiers = Qt.NoModifier
399+
modifiers = Qt.KeyboardModifier.NoModifier
400400

401401
for modifier in event_list[0:-1]:
402402
if modifier == "C":
403-
modifiers |= Qt.ControlModifier
403+
modifiers |= Qt.KeyboardModifier.ControlModifier
404404
elif modifier == "M":
405-
modifiers |= Qt.AltModifier
405+
modifiers |= Qt.KeyboardModifier.AltModifier
406406
elif modifier == "S":
407-
modifiers |= Qt.ShiftModifier
407+
modifiers |= Qt.KeyboardModifier.KeyboardModifier.ShiftModifier
408408
elif modifier == "s":
409-
modifiers |= Qt.MetaModifier
409+
modifiers |= Qt.KeyboardModifier.MetaModifier
410410

411-
QApplication.sendEvent(widget, QKeyEvent(QEvent.KeyPress, qt_key_dict[last_key], modifiers, last_key))
411+
QApplication.sendEvent(widget, QKeyEvent(QEvent.Type.KeyPress, qt_key_dict[last_key], modifiers, last_key))
412412

413413
def get_url(self):
414414
''' Get url.'''
@@ -440,7 +440,7 @@ def select_right_tab(self):
440440
def focus_widget(self, event=None):
441441
'''Focus buffer widget.'''
442442
if event is None:
443-
event = QFocusEvent(QEvent.FocusIn, Qt.MouseFocusReason)
443+
event = QFocusEvent(QEvent.Type.FocusIn, Qt.FocusReason.MouseFocusReason)
444444
QApplication.sendEvent(self.buffer_widget.focusProxy(), event)
445445

446446
# Activate emacs window when call focus widget, avoid first char is not

core/utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
# You should have received a copy of the GNU General Public License
2020
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2121

22-
from PyQt5.QtCore import QObject, pyqtSignal
22+
from PyQt6.QtCore import QObject, pyqtSignal
2323

2424
class PostGui(QObject):
2525

@@ -147,8 +147,8 @@ def run_in_thread(on_exit, popen_args):
147147

148148
def get_clipboard_text():
149149
''' Get text from system clipboard.'''
150-
from PyQt5.QtWidgets import QApplication
151-
from PyQt5.QtGui import QClipboard
150+
from PyQt6.QtWidgets import QApplication
151+
from PyQt6.QtGui import QClipboard
152152

153153
clipboard = QApplication.clipboard()
154154
text = clipboard.text()
@@ -162,8 +162,8 @@ def get_clipboard_text():
162162

163163
def set_clipboard_text(text):
164164
''' Set text to system clipboard.'''
165-
from PyQt5.QtWidgets import QApplication
166-
from PyQt5.QtGui import QClipboard
165+
from PyQt6.QtWidgets import QApplication
166+
from PyQt6.QtGui import QClipboard
167167

168168
clipboard = QApplication.clipboard()
169169
clipboard.setText(text)

core/view.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
# You should have received a copy of the GNU General Public License
2020
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2121

22-
from PyQt5.QtCore import Qt, QEvent, QPoint
23-
from PyQt5.QtGui import QPainter, QWindow, QBrush
24-
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QGraphicsView, QFrame
22+
from PyQt6.QtCore import Qt, QEvent, QPoint
23+
from PyQt6.QtGui import QPainter, QWindow, QBrush
24+
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QGraphicsView, QFrame
2525
from core.utils import eval_in_emacs, focus_emacs_buffer, get_emacs_func_result
2626

2727
class View(QWidget):
@@ -33,13 +33,13 @@ def __init__(self, buffer, view_info):
3333

3434
# Init widget attributes.
3535
if get_emacs_func_result("eaf-emacs-running-in-wayland-native", []):
36-
self.setWindowFlags(Qt.FramelessWindowHint | Qt.BypassWindowManagerHint)
36+
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.BypassWindowManagerHint)
3737
elif get_emacs_func_result("eaf-emacs-not-use-reparent-technology", []):
38-
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.NoDropShadowWindowHint)
38+
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint | Qt.WindowType.NoDropShadowWindowHint)
3939
else:
40-
self.setWindowFlags(Qt.FramelessWindowHint)
40+
self.setWindowFlags(Qt.WindowType.FramelessWindowHint)
4141

42-
self.setAttribute(Qt.WA_X11DoNotAcceptFocus, True)
42+
self.setAttribute(Qt.WidgetAttribute.WA_X11DoNotAcceptFocus, True)
4343
self.setContentsMargins(0, 0, 0, 0)
4444
self.installEventFilter(self)
4545

@@ -58,10 +58,10 @@ def __init__(self, buffer, view_info):
5858
self.graphics_view = QGraphicsView(buffer, self)
5959

6060
# Remove border from QGraphicsView.
61-
self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
62-
self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
63-
self.graphics_view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)
64-
self.graphics_view.setFrameStyle(QFrame.NoFrame)
61+
self.graphics_view.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
62+
self.graphics_view.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
63+
self.graphics_view.setRenderHints(QPainter.RenderHint.Antialiasing | QPainter.RenderHint.SmoothPixmapTransform | QPainter.RenderHint.TextAntialiasing)
64+
self.graphics_view.setFrameStyle(QFrame.Shape.NoFrame)
6565

6666
# Fill background color.
6767
self.graphics_view.setBackgroundBrush(QBrush(buffer.background_color))
@@ -81,7 +81,7 @@ def resizeEvent(self, event):
8181
# Fit content to view rect just when buffer fit_to_view option is enable.
8282
if self.buffer.fit_to_view:
8383
if event.oldSize().isValid():
84-
self.graphics_view.fitInView(self.graphics_view.scene().sceneRect(), Qt.KeepAspectRatio)
84+
self.graphics_view.fitInView(self.graphics_view.scene().sceneRect(), Qt.AspectRatioMode.KeepAspectRatio)
8585
QWidget.resizeEvent(self, event)
8686

8787
def adjust_aspect_ratio(self):
@@ -110,13 +110,13 @@ def eventFilter(self, obj, event):
110110

111111
import platform
112112

113-
if event.type() in [QEvent.ShortcutOverride]:
113+
if event.type() in [QEvent.Type.ShortcutOverride]:
114114
eval_in_emacs('eaf-activate-emacs-window', [self.buffer_id])
115115

116116
# Focus emacs buffer when user click view.
117-
event_type = [QEvent.MouseButtonPress, QEvent.MouseButtonRelease, QEvent.MouseButtonDblClick]
117+
event_type = [QEvent.Type.MouseButtonPress, QEvent.Type.MouseButtonRelease, QEvent.Type.MouseButtonDblClick]
118118
if platform.system() != "Darwin":
119-
event_type += [QEvent.Wheel]
119+
event_type += [QEvent.Type.Wheel]
120120

121121
if event.type() in event_type:
122122
focus_emacs_buffer(self.buffer_id)
@@ -149,12 +149,12 @@ def reparent(self):
149149

150150
def try_show_top_view(self):
151151
if get_emacs_func_result("eaf-emacs-not-use-reparent-technology", []):
152-
self.setWindowFlag(Qt.WindowStaysOnTopHint, True)
152+
self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint, True)
153153
self.show()
154154

155155
def try_hide_top_view(self):
156156
if get_emacs_func_result("eaf-emacs-not-use-reparent-technology", []):
157-
self.setWindowFlag(Qt.WindowStaysOnTopHint, False)
157+
self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint, False)
158158
self.hide()
159159

160160
def destroy_view(self):

0 commit comments

Comments
 (0)