More workarounds for the broken underMouse() function in Qt 5 on X11

Fixes buttons on the toolbar remaining raised even after their popup
menus are closed.
This commit is contained in:
Kovid Goyal 2014-07-15 10:35:43 +05:30
parent 81d1a3b922
commit b00781b87a
4 changed files with 41 additions and 7 deletions

View File

@ -1152,3 +1152,14 @@ if _df and os.path.exists(_df):
build_forms(_df)
if islinux or isbsd:
def workaround_broken_under_mouse(ch):
import sip
from PyQt5.Qt import QCursor, QToolButton
# See https://bugreports.qt-project.org/browse/QTBUG-40233
if isinstance(ch, QToolButton) and not sip.isdeleted(ch):
ch.setAttribute(Qt.WA_UnderMouse, ch.rect().contains(ch.mapFromGlobal(QCursor.pos())))
ch.update()
else:
workaround_broken_under_mouse = None

View File

@ -7,13 +7,15 @@ __license__ = 'GPL v3'
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from functools import partial
import sip
from PyQt5.Qt import (Qt, QAction, QMenu, QMenuBar, QObject,
QToolBar, QToolButton, QSize, pyqtSignal, QTimer)
from calibre.constants import isosx
from calibre.gui2.throbber import create_donate_widget
from calibre.gui2 import gprefs
from calibre.gui2 import gprefs, workaround_broken_under_mouse
class ToolBar(QToolBar): # {{{
@ -106,8 +108,12 @@ class ToolBar(QToolBar): # {{{
ch = self.child_bar.widgetForAction(ac)
ch.setCursor(Qt.PointingHandCursor)
ch.setAutoRaise(True)
if ac.menu() is not None and menu_mode is not None:
ch.setPopupMode(menu_mode)
m = ac.menu()
if m is not None:
if workaround_broken_under_mouse is not None:
m.aboutToHide.connect(partial(workaround_broken_under_mouse, ch))
if menu_mode is not None:
ch.setPopupMode(menu_mode)
return ch
# support drag&drop from/to library, from/to reader/card, enabled plugins

View File

@ -16,8 +16,8 @@ from PyQt5.Qt import (
from calibre import prints
from calibre.constants import DEBUG
from calibre.ebooks.chardet import replace_encoding_declarations
from calibre.gui2 import error_dialog, open_url
from calibre.gui2.tweak_book import actions, current_container, tprefs, dictionaries, editor_toolbar_actions, editor_name, editors
from calibre.gui2 import error_dialog, open_url, workaround_broken_under_mouse
from calibre.gui2.tweak_book.editor import SPELL_PROPERTY, LINK_PROPERTY, TAG_NAME_PROPERTY, CSS_PROPERTY
from calibre.gui2.tweak_book.editor.help import help_url
from calibre.gui2.tweak_book.editor.text import TextEdit
@ -310,10 +310,19 @@ class Editor(QMainWindow):
w.setContextMenuPolicy(Qt.CustomContextMenu)
w.customContextMenuRequested.connect(w.showMenu)
self._build_insert_tag_button_menu()
if workaround_broken_under_mouse is not None:
try:
self.insert_tag_menu.aboutToHide.disconnect()
except TypeError:
pass
self.insert_tag_menu.aboutToHide.connect(partial(workaround_broken_under_mouse, w))
elif name == 'change-paragraph':
m = ac.m = QMenu()
ac.setMenu(m)
bar.widgetForAction(ac).setPopupMode(QToolButton.InstantPopup)
ch = bar.widgetForAction(ac)
ch.setPopupMode(QToolButton.InstantPopup)
if workaround_broken_under_mouse is not None:
m.aboutToHide.connect(partial(workaround_broken_under_mouse, ch))
for name in tuple('h%d' % d for d in range(1, 7)) + ('p',):
m.addAction(actions['rename-block-tag-%s' % name])

View File

@ -13,8 +13,10 @@ from calibre.gui2.viewer.ui import Main as MainWindow
from calibre.gui2.viewer.printing import Printing
from calibre.gui2.viewer.toc import TOC
from calibre.gui2.widgets import ProgressIndicator
from calibre.gui2 import (Application, ORG_NAME, APP_UID, choose_files,
info_dialog, error_dialog, open_url, setup_gui_option_parser, detach_gui)
from calibre.gui2 import (
Application, ORG_NAME, APP_UID, choose_files, info_dialog, error_dialog,
open_url, setup_gui_option_parser, detach_gui,
workaround_broken_under_mouse)
from calibre.ebooks.oeb.iterator.book import EbookIterator
from calibre.ebooks import DRMError
from calibre.constants import islinux, filesystem_encoding
@ -154,6 +156,12 @@ class EbookViewer(MainWindow):
self.action_toggle_paged_mode.toggled[bool].connect(self.toggle_paged_mode)
if (start_in_fullscreen or self.view.document.start_in_fullscreen):
self.action_full_screen.trigger()
if workaround_broken_under_mouse is not None:
for bar in (self.tool_bar, self.tool_bar2):
for ac in bar.actions():
m = ac.menu()
if m is not None:
m.aboutToHide.connect(partial(workaround_broken_under_mouse, bar.widgetForAction(ac)))
def toggle_paged_mode(self, checked, at_start=False):
in_paged_mode = not self.action_toggle_paged_mode.isChecked()