mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-30 17:24:08 +00:00
Merge pull request #995 from vedgy/x11-fix-unpinned-scan-popup-option
Allow customizing unpinned scan popup window flags on X11 with Qt5
This commit is contained in:
commit
b34ac9630e
24
config.cc
24
config.cc
|
@ -128,6 +128,18 @@ bool InternalPlayerBackend::isQtmultimedia() const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScanPopupWindowFlags spwfFromInt( int id )
|
||||||
|
{
|
||||||
|
if( id == SPWF_Popup )
|
||||||
|
return SPWF_Popup;
|
||||||
|
if( id == SPWF_Tool )
|
||||||
|
return SPWF_Tool;
|
||||||
|
|
||||||
|
if( id != SPWF_default )
|
||||||
|
gdWarning( "Invalid ScanPopup unpinned window flags: %d\n", id );
|
||||||
|
return SPWF_default;
|
||||||
|
}
|
||||||
|
|
||||||
Preferences::Preferences():
|
Preferences::Preferences():
|
||||||
newTabsOpenAfterCurrentOne( false ),
|
newTabsOpenAfterCurrentOne( false ),
|
||||||
newTabsOpenInBackground( true ),
|
newTabsOpenInBackground( true ),
|
||||||
|
@ -158,6 +170,8 @@ Preferences::Preferences():
|
||||||
scanPopupUseUIAutomation( true ),
|
scanPopupUseUIAutomation( true ),
|
||||||
scanPopupUseIAccessibleEx( true ),
|
scanPopupUseIAccessibleEx( true ),
|
||||||
scanPopupUseGDMessage( true ),
|
scanPopupUseGDMessage( true ),
|
||||||
|
scanPopupUnpinnedWindowFlags( SPWF_default ),
|
||||||
|
scanPopupUnpinnedBypassWMHint( false ),
|
||||||
scanToMainWindow( false ),
|
scanToMainWindow( false ),
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
showScanFlag( false ),
|
showScanFlag( false ),
|
||||||
|
@ -812,6 +826,8 @@ Class load() throw( exError )
|
||||||
c.preferences.scanPopupUseUIAutomation = ( preferences.namedItem( "scanPopupUseUIAutomation" ).toElement().text() == "1" );
|
c.preferences.scanPopupUseUIAutomation = ( preferences.namedItem( "scanPopupUseUIAutomation" ).toElement().text() == "1" );
|
||||||
c.preferences.scanPopupUseIAccessibleEx = ( preferences.namedItem( "scanPopupUseIAccessibleEx" ).toElement().text() == "1" );
|
c.preferences.scanPopupUseIAccessibleEx = ( preferences.namedItem( "scanPopupUseIAccessibleEx" ).toElement().text() == "1" );
|
||||||
c.preferences.scanPopupUseGDMessage = ( preferences.namedItem( "scanPopupUseGDMessage" ).toElement().text() == "1" );
|
c.preferences.scanPopupUseGDMessage = ( preferences.namedItem( "scanPopupUseGDMessage" ).toElement().text() == "1" );
|
||||||
|
c.preferences.scanPopupUnpinnedWindowFlags = spwfFromInt( preferences.namedItem( "scanPopupUnpinnedWindowFlags" ).toElement().text().toInt() );
|
||||||
|
c.preferences.scanPopupUnpinnedBypassWMHint = ( preferences.namedItem( "scanPopupUnpinnedBypassWMHint" ).toElement().text() == "1" );
|
||||||
|
|
||||||
c.preferences.pronounceOnLoadMain = ( preferences.namedItem( "pronounceOnLoadMain" ).toElement().text() == "1" );
|
c.preferences.pronounceOnLoadMain = ( preferences.namedItem( "pronounceOnLoadMain" ).toElement().text() == "1" );
|
||||||
c.preferences.pronounceOnLoadPopup = ( preferences.namedItem( "pronounceOnLoadPopup" ).toElement().text() == "1" );
|
c.preferences.pronounceOnLoadPopup = ( preferences.namedItem( "pronounceOnLoadPopup" ).toElement().text() == "1" );
|
||||||
|
@ -1702,6 +1718,14 @@ void save( Class const & c ) throw( exError )
|
||||||
opt.appendChild( dd.createTextNode( c.preferences.scanPopupUseGDMessage ? "1":"0" ) );
|
opt.appendChild( dd.createTextNode( c.preferences.scanPopupUseGDMessage ? "1":"0" ) );
|
||||||
preferences.appendChild( opt );
|
preferences.appendChild( opt );
|
||||||
|
|
||||||
|
opt = dd.createElement( "scanPopupUnpinnedWindowFlags" );
|
||||||
|
opt.appendChild( dd.createTextNode( QString::number( c.preferences.scanPopupUnpinnedWindowFlags ) ) );
|
||||||
|
preferences.appendChild( opt );
|
||||||
|
|
||||||
|
opt = dd.createElement( "scanPopupUnpinnedBypassWMHint" );
|
||||||
|
opt.appendChild( dd.createTextNode( c.preferences.scanPopupUnpinnedBypassWMHint ? "1":"0" ) );
|
||||||
|
preferences.appendChild( opt );
|
||||||
|
|
||||||
opt = dd.createElement( "pronounceOnLoadMain" );
|
opt = dd.createElement( "pronounceOnLoadMain" );
|
||||||
opt.appendChild( dd.createTextNode( c.preferences.pronounceOnLoadMain ? "1" : "0" ) );
|
opt.appendChild( dd.createTextNode( c.preferences.pronounceOnLoadMain ? "1" : "0" ) );
|
||||||
preferences.appendChild( opt );
|
preferences.appendChild( opt );
|
||||||
|
|
19
config.hh
19
config.hh
|
@ -225,6 +225,23 @@ private:
|
||||||
QString name;
|
QString name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined( HAVE_X11 ) && QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
|
||||||
|
// The ScanPopup window flags customization code has been tested
|
||||||
|
// only in X11 desktop environments and window managers.
|
||||||
|
// None of the window flags configurations I have tried works perfectly well
|
||||||
|
// in XFCE with Qt4. Let us enable customization code for Qt5 exclusively to
|
||||||
|
// avoid regressions with Qt4.
|
||||||
|
#define ENABLE_SPWF_CUSTOMIZATION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum ScanPopupWindowFlags
|
||||||
|
{
|
||||||
|
SPWF_default = 0,
|
||||||
|
SPWF_Popup,
|
||||||
|
SPWF_Tool
|
||||||
|
};
|
||||||
|
ScanPopupWindowFlags spwfFromInt( int id );
|
||||||
|
|
||||||
/// Various user preferences
|
/// Various user preferences
|
||||||
struct Preferences
|
struct Preferences
|
||||||
{
|
{
|
||||||
|
@ -263,6 +280,8 @@ struct Preferences
|
||||||
bool scanPopupUseUIAutomation;
|
bool scanPopupUseUIAutomation;
|
||||||
bool scanPopupUseIAccessibleEx;
|
bool scanPopupUseIAccessibleEx;
|
||||||
bool scanPopupUseGDMessage;
|
bool scanPopupUseGDMessage;
|
||||||
|
ScanPopupWindowFlags scanPopupUnpinnedWindowFlags;
|
||||||
|
bool scanPopupUnpinnedBypassWMHint;
|
||||||
bool scanToMainWindow;
|
bool scanToMainWindow;
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
bool showScanFlag;
|
bool showScanFlag;
|
||||||
|
|
|
@ -191,6 +191,8 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
|
||||||
ui.scanPopupUseUIAutomation->setChecked( p.scanPopupUseUIAutomation );
|
ui.scanPopupUseUIAutomation->setChecked( p.scanPopupUseUIAutomation );
|
||||||
ui.scanPopupUseIAccessibleEx->setChecked( p.scanPopupUseIAccessibleEx );
|
ui.scanPopupUseIAccessibleEx->setChecked( p.scanPopupUseIAccessibleEx );
|
||||||
ui.scanPopupUseGDMessage->setChecked( p.scanPopupUseGDMessage );
|
ui.scanPopupUseGDMessage->setChecked( p.scanPopupUseGDMessage );
|
||||||
|
ui.scanPopupUnpinnedWindowFlags->setCurrentIndex( p.scanPopupUnpinnedWindowFlags );
|
||||||
|
ui.scanPopupUnpinnedBypassWMHint->setChecked( p.scanPopupUnpinnedBypassWMHint );
|
||||||
|
|
||||||
ui.storeHistory->setChecked( p.storeHistory );
|
ui.storeHistory->setChecked( p.storeHistory );
|
||||||
ui.historyMaxSizeField->setValue( p.maxStringsInHistory );
|
ui.historyMaxSizeField->setValue( p.maxStringsInHistory );
|
||||||
|
@ -232,6 +234,10 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
|
||||||
// ui.tabWidget->removeTab( 5 );
|
// ui.tabWidget->removeTab( 5 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENABLE_SPWF_CUSTOMIZATION
|
||||||
|
ui.groupBox_ScanPopupWindowFlags->hide();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_X11
|
#ifdef HAVE_X11
|
||||||
ui.showScanFlag->setChecked( p.showScanFlag);
|
ui.showScanFlag->setChecked( p.showScanFlag);
|
||||||
#else
|
#else
|
||||||
|
@ -395,6 +401,8 @@ Config::Preferences Preferences::getPreferences()
|
||||||
p.scanPopupUseUIAutomation = ui.scanPopupUseUIAutomation->isChecked();
|
p.scanPopupUseUIAutomation = ui.scanPopupUseUIAutomation->isChecked();
|
||||||
p.scanPopupUseIAccessibleEx = ui.scanPopupUseIAccessibleEx->isChecked();
|
p.scanPopupUseIAccessibleEx = ui.scanPopupUseIAccessibleEx->isChecked();
|
||||||
p.scanPopupUseGDMessage = ui.scanPopupUseGDMessage->isChecked();
|
p.scanPopupUseGDMessage = ui.scanPopupUseGDMessage->isChecked();
|
||||||
|
p.scanPopupUnpinnedWindowFlags = Config::spwfFromInt( ui.scanPopupUnpinnedWindowFlags->currentIndex() );
|
||||||
|
p.scanPopupUnpinnedBypassWMHint = ui.scanPopupUnpinnedBypassWMHint->isChecked();
|
||||||
|
|
||||||
p.storeHistory = ui.storeHistory->isChecked();
|
p.storeHistory = ui.storeHistory->isChecked();
|
||||||
p.maxStringsInHistory = ui.historyMaxSizeField->text().toUInt();
|
p.maxStringsInHistory = ui.historyMaxSizeField->text().toUInt();
|
||||||
|
@ -543,6 +551,11 @@ void Preferences::showScanFlagToggled( bool b )
|
||||||
ui.enableScanPopupModifiers->setChecked( false );
|
ui.enableScanPopupModifiers->setChecked( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Preferences::on_scanPopupUnpinnedWindowFlags_currentIndexChanged( int index )
|
||||||
|
{
|
||||||
|
ui.scanPopupUnpinnedBypassWMHint->setEnabled( Config::spwfFromInt( index ) != Config::SPWF_default );
|
||||||
|
}
|
||||||
|
|
||||||
void Preferences::wholeAltClicked( bool b )
|
void Preferences::wholeAltClicked( bool b )
|
||||||
{
|
{
|
||||||
if ( b )
|
if ( b )
|
||||||
|
|
|
@ -34,6 +34,7 @@ private slots:
|
||||||
void enableScanPopupToggled( bool );
|
void enableScanPopupToggled( bool );
|
||||||
void enableScanPopupModifiersToggled( bool );
|
void enableScanPopupModifiersToggled( bool );
|
||||||
void showScanFlagToggled( bool b );
|
void showScanFlagToggled( bool b );
|
||||||
|
void on_scanPopupUnpinnedWindowFlags_currentIndexChanged( int index );
|
||||||
|
|
||||||
void wholeAltClicked( bool );
|
void wholeAltClicked( bool );
|
||||||
void wholeCtrlClicked( bool );
|
void wholeCtrlClicked( bool );
|
||||||
|
|
|
@ -1369,6 +1369,8 @@ download page.</string>
|
||||||
<string>Ad&vanced</string>
|
<string>Ad&vanced</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_17">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_ScanPopupTechnologies">
|
<widget class="QGroupBox" name="groupBox_ScanPopupTechnologies">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -1415,6 +1417,78 @@ It is not needed to select this option if you don't use such programs.</string>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_ScanPopupWindowFlags">
|
||||||
|
<property name="title">
|
||||||
|
<string>ScanPopup unpinned window flags</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_22">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="scanPopupUnpinnedWindowFlags">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Experiment with non-default flags if the unpinned scan popup window misbehaves</string>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string><default></string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Popup</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Tool</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="scanPopupUnpinnedBypassWMHint">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>This hint can be combined with non-default window flags</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Bypass window manager hint</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_18">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_13">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||||
<item>
|
<item>
|
||||||
|
|
46
scanpopup.cc
46
scanpopup.cc
|
@ -24,7 +24,7 @@ using std::wstring;
|
||||||
|
|
||||||
/// We use different window flags under Windows and X11 due to slight differences
|
/// We use different window flags under Windows and X11 due to slight differences
|
||||||
/// in their behavior on those platforms.
|
/// in their behavior on those platforms.
|
||||||
static Qt::WindowFlags popupWindowFlags =
|
static const Qt::WindowFlags defaultUnpinnedWindowFlags =
|
||||||
|
|
||||||
#if defined (Q_OS_WIN) || ( defined (Q_OS_MAC) && QT_VERSION < QT_VERSION_CHECK( 5, 3, 0 ) )
|
#if defined (Q_OS_WIN) || ( defined (Q_OS_MAC) && QT_VERSION < QT_VERSION_CHECK( 5, 3, 0 ) )
|
||||||
Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
|
Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
|
||||||
|
@ -177,7 +177,7 @@ ScanPopup::ScanPopup( QWidget * parent,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dictionaryBar.setMovable( false );
|
dictionaryBar.setMovable( false );
|
||||||
setWindowFlags( popupWindowFlags );
|
setWindowFlags( unpinnedWindowFlags() );
|
||||||
}
|
}
|
||||||
|
|
||||||
connect( &configEvents, SIGNAL( mutedDictionariesChanged() ),
|
connect( &configEvents, SIGNAL( mutedDictionariesChanged() ),
|
||||||
|
@ -387,6 +387,27 @@ void ScanPopup::applyWordsZoomLevel()
|
||||||
ui.groupList->parentWidget()->layout()->activate();
|
ui.groupList->parentWidget()->layout()->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::WindowFlags ScanPopup::unpinnedWindowFlags() const
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_SPWF_CUSTOMIZATION
|
||||||
|
const Config::ScanPopupWindowFlags spwf = cfg.preferences.scanPopupUnpinnedWindowFlags;
|
||||||
|
Qt::WindowFlags result;
|
||||||
|
if( spwf == Config::SPWF_Popup )
|
||||||
|
result = Qt::Popup;
|
||||||
|
else
|
||||||
|
if( spwf == Config::SPWF_Tool )
|
||||||
|
result = Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint;
|
||||||
|
else
|
||||||
|
return defaultUnpinnedWindowFlags; // Ignore BypassWMHint option.
|
||||||
|
|
||||||
|
if( cfg.preferences.scanPopupUnpinnedBypassWMHint )
|
||||||
|
result |= Qt::X11BypassWindowManagerHint;
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
return defaultUnpinnedWindowFlags;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void ScanPopup::translateWordFromClipboard()
|
void ScanPopup::translateWordFromClipboard()
|
||||||
{
|
{
|
||||||
return translateWordFromClipboard(QClipboard::Clipboard);
|
return translateWordFromClipboard(QClipboard::Clipboard);
|
||||||
|
@ -584,6 +605,14 @@ void ScanPopup::engagePopup( bool forcePopup, bool giveFocus )
|
||||||
|
|
||||||
show();
|
show();
|
||||||
|
|
||||||
|
#ifdef ENABLE_SPWF_CUSTOMIZATION
|
||||||
|
// Ensure that the window always has focus on X11 with Qt::Tool flag.
|
||||||
|
// This also often prevents the window from disappearing prematurely with Qt::Popup flag,
|
||||||
|
// especially when combined with Qt::X11BypassWindowManagerHint flag.
|
||||||
|
if ( !ui.pinButton->isChecked() )
|
||||||
|
giveFocus = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( giveFocus )
|
if ( giveFocus )
|
||||||
{
|
{
|
||||||
activateWindow();
|
activateWindow();
|
||||||
|
@ -608,6 +637,15 @@ void ScanPopup::engagePopup( bool forcePopup, bool giveFocus )
|
||||||
activateWindow();
|
activateWindow();
|
||||||
raise();
|
raise();
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_SPWF_CUSTOMIZATION
|
||||||
|
else
|
||||||
|
if ( ( windowFlags() & Qt::Tool ) == Qt::Tool )
|
||||||
|
{
|
||||||
|
// Ensure that the window with Qt::Tool flag always has focus on X11.
|
||||||
|
activateWindow();
|
||||||
|
raise();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( ui.pinButton->isChecked() )
|
if ( ui.pinButton->isChecked() )
|
||||||
setWindowTitle( tr( "%1 - %2" ).arg( elideInputWord(), "GoldenDict" ) );
|
setWindowTitle( tr( "%1 - %2" ).arg( elideInputWord(), "GoldenDict" ) );
|
||||||
|
@ -906,7 +944,7 @@ void ScanPopup::requestWindowFocus()
|
||||||
// One of the rare, actually working workarounds for requesting a user keyboard focus on X11,
|
// One of the rare, actually working workarounds for requesting a user keyboard focus on X11,
|
||||||
// works for Qt::Popup windows, exactly like our Scan Popup (in unpinned state).
|
// works for Qt::Popup windows, exactly like our Scan Popup (in unpinned state).
|
||||||
// Modern window managers actively resist to automatically focus pop-up windows.
|
// Modern window managers actively resist to automatically focus pop-up windows.
|
||||||
#ifdef HAVE_X11
|
#if defined HAVE_X11 && QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
|
||||||
if ( !ui.pinButton->isChecked() )
|
if ( !ui.pinButton->isChecked() )
|
||||||
{
|
{
|
||||||
QMenu m( this );
|
QMenu m( this );
|
||||||
|
@ -973,7 +1011,7 @@ void ScanPopup::pinButtonClicked( bool checked )
|
||||||
{
|
{
|
||||||
ui.onTopButton->setVisible( false );
|
ui.onTopButton->setVisible( false );
|
||||||
dictionaryBar.setMovable( false );
|
dictionaryBar.setMovable( false );
|
||||||
setWindowFlags( popupWindowFlags );
|
setWindowFlags( unpinnedWindowFlags() );
|
||||||
|
|
||||||
mouseEnteredOnce = true;
|
mouseEnteredOnce = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,8 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
Qt::WindowFlags unpinnedWindowFlags() const;
|
||||||
|
|
||||||
// Translates the word from the clipboard or the clipboard selection
|
// Translates the word from the clipboard or the clipboard selection
|
||||||
void translateWordFromClipboard(QClipboard::Mode m);
|
void translateWordFromClipboard(QClipboard::Mode m);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue