Linux-specific: Add an option to disable scan popup inside Goldendict

When scan popup is configured to appear without any key modifiers
pressed and is active on X11, it interferes with selecting text inside
the scan popup window (or inside the main window if "Send translated
word to main window" option is enabled). It also makes searching text
inside article definition impossible - in the main window and
even more so in the scan popup window.

However, when scan popup is configured to appear only when some keys are
pressed, or when the scan flag feature is enabled, it may work fine
inside Goldendict windows.

It is possible to automatically decide whether to show scan popup when
selection or clipboard inside Goldendict changes. But such logic might
be unsuitable for some use cases. For example, invoking scan popup by
selecting article definition text in the main window works fine.
Therefore this commit makes ignoring selection and clipboard changes
inside Goldendict itself optional. This commit implements one of two
feature requests in issue #606.

This new option could have effect on non-X11 platforms if the hidden
trackClipboardChanges option is enabled. But it is much less useful on
these platforms because scan popup without key modifiers is unusable
there (at least under Windows). Let us show and use the option only on
X11 to avoid cluttering Preferences UI on other platforms.
This commit is contained in:
Igor Kushnir 2018-04-16 15:23:22 +03:00
parent b34ac9630e
commit 5c74494935
5 changed files with 41 additions and 0 deletions

View file

@ -167,6 +167,7 @@ Preferences::Preferences():
scanPopupModifiers( 0 ),
scanPopupAltMode( false ),
scanPopupAltModeSecs( 3 ),
ignoreOwnClipboardChanges( false ),
scanPopupUseUIAutomation( true ),
scanPopupUseIAccessibleEx( true ),
scanPopupUseGDMessage( true ),
@ -819,6 +820,7 @@ Class load() throw( exError )
c.preferences.scanPopupAltMode = ( preferences.namedItem( "scanPopupAltMode" ).toElement().text() == "1" );
if ( !preferences.namedItem( "scanPopupAltModeSecs" ).isNull() )
c.preferences.scanPopupAltModeSecs = preferences.namedItem( "scanPopupAltModeSecs" ).toElement().text().toUInt();
c.preferences.ignoreOwnClipboardChanges = ( preferences.namedItem( "ignoreOwnClipboardChanges" ).toElement().text() == "1" );
c.preferences.scanToMainWindow = ( preferences.namedItem( "scanToMainWindow" ).toElement().text() == "1" );
#ifdef HAVE_X11
c.preferences.showScanFlag= ( preferences.namedItem( "showScanFlag" ).toElement().text() == "1" );
@ -1696,6 +1698,10 @@ void save( Class const & c ) throw( exError )
opt.appendChild( dd.createTextNode( QString::number( c.preferences.scanPopupAltModeSecs ) ) );
preferences.appendChild( opt );
opt = dd.createElement( "ignoreOwnClipboardChanges" );
opt.appendChild( dd.createTextNode( c.preferences.ignoreOwnClipboardChanges ? "1":"0" ) );
preferences.appendChild( opt );
opt = dd.createElement( "scanToMainWindow" );
opt.appendChild( dd.createTextNode( c.preferences.scanToMainWindow ? "1":"0" ) );
preferences.appendChild( opt );

View file

@ -277,6 +277,7 @@ struct Preferences
unsigned long scanPopupModifiers; // Combination of KeyboardState::Modifier
bool scanPopupAltMode; // When you press modifier shortly after the selection
unsigned scanPopupAltModeSecs;
bool ignoreOwnClipboardChanges;
bool scanPopupUseUIAutomation;
bool scanPopupUseIAccessibleEx;
bool scanPopupUseGDMessage;

View file

@ -187,6 +187,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
ui.scanPopupAltMode->setChecked( p.scanPopupAltMode );
ui.scanPopupAltModeSecs->setValue( p.scanPopupAltModeSecs );
ui.ignoreOwnClipboardChanges->setChecked( p.ignoreOwnClipboardChanges );
ui.scanToMainWindow->setChecked( p.scanToMainWindow );
ui.scanPopupUseUIAutomation->setChecked( p.scanPopupUseUIAutomation );
ui.scanPopupUseIAccessibleEx->setChecked( p.scanPopupUseIAccessibleEx );
@ -242,6 +243,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ):
ui.showScanFlag->setChecked( p.showScanFlag);
#else
ui.showScanFlag->hide();
ui.ignoreOwnClipboardChanges->hide();
#endif
// Sound
@ -394,6 +396,7 @@ Config::Preferences Preferences::getPreferences()
p.scanPopupAltMode = ui.scanPopupAltMode->isChecked();
p.scanPopupAltModeSecs = ui.scanPopupAltModeSecs->value();
p.ignoreOwnClipboardChanges = ui.ignoreOwnClipboardChanges->isChecked();
p.scanToMainWindow = ui.scanToMainWindow->isChecked();
#ifdef HAVE_X11
p.showScanFlag= ui.showScanFlag->isChecked();

View file

@ -689,6 +689,16 @@ seconds, which is specified here.</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ignoreOwnClipboardChanges">
<property name="toolTip">
<string>Do not show popup when selection or clipboard in one of Goldendict's own windows changes</string>
</property>
<property name="text">
<string>Ignore Goldendict's own selection and clipboard changes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -33,6 +33,23 @@ Qt::Popup
#endif
;
static bool ownsClipboardMode( QClipboard::Mode mode )
{
const QClipboard & clipboard = *QApplication::clipboard();
switch( mode )
{
case QClipboard::Clipboard:
return clipboard.ownsClipboard();
case QClipboard::Selection:
return clipboard.ownsSelection();
case QClipboard::FindBuffer:
return clipboard.ownsFindBuffer();
}
gdWarning( "Unknown clipboard mode: %d\n", static_cast< int >( mode ) );
return false;
}
ScanPopup::ScanPopup( QWidget * parent,
Config::Class & cfg_,
ArticleNetworkAccessManager & articleNetMgr,
@ -472,6 +489,10 @@ void ScanPopup::clipboardChanged( QClipboard::Mode m )
{
if ( !isScanningEnabled )
return;
#ifdef HAVE_X11
if( cfg.preferences.ignoreOwnClipboardChanges && ownsClipboardMode( m ) )
return;
#endif
GD_DPRINTF( "clipboard changed\n" );