kdeui: pass the associated action from KKeySequenceWidget to KGlobalAccel

for better shortcut stealing, e.g. for actions with more than one
shortcut

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-04-27 04:48:57 +03:00
parent 98f6b2b434
commit 9dfe6602a9
3 changed files with 30 additions and 36 deletions

View file

@ -274,9 +274,12 @@ QList<KGlobalShortcutInfo> KGlobalAccel::getGlobalShortcutsByKey(const QKeySeque
return result;
}
bool KGlobalAccel::isGlobalShortcutAvailable(const QKeySequence &seq, const QString &comp)
bool KGlobalAccel::isGlobalShortcutAvailable(const QKeySequence &seq, const QAction *exception)
{
foreach (const KGlobalAccelStruct &shortcut, d->filter->shortcuts) {
if (shortcut.action == exception) {
continue;
}
if (shortcut.action->globalShortcut().matches(seq) != QKeySequence::NoMatch) {
return false;
}
@ -284,15 +287,17 @@ bool KGlobalAccel::isGlobalShortcutAvailable(const QKeySequence &seq, const QStr
return true;
}
void KGlobalAccel::stealShortcutSystemwide(const QKeySequence &seq)
void KGlobalAccel::stealShortcutSystemwide(const QKeySequence &seq, const QAction *exception)
{
foreach (const KGlobalAccelStruct &shortcut, d->filter->shortcuts) {
if (shortcut.action == exception) {
continue;
}
if (shortcut.action->globalShortcut().matches(seq) != QKeySequence::NoMatch) {
// TODO: in case of partial match this can steal only the matching one
kDebug(s_kglobalaccelarea) << "stealing shortcut" << seq << "from" << shortcut.action;
shortcut.action->setGlobalShortcut(QKeySequence());
shortcut.action->setGlobalShortcut(QKeySequence(), KAction::ActiveShortcut);
d->remove(shortcut.action);
break;
}
}
}

View file

@ -38,12 +38,12 @@ struct KGlobalShortcutInfo
/**
* @short Configurable global shortcut support
*
* KGlobalAccel allows you to have global accelerators that are independent of
* the focused window. Unlike regular shortcuts, the application's window does not need focus
* for them to be activated.
* KGlobalAccel allows you to have global accelerators that are independent of the focused window.
* Unlike regular shortcuts, the application's window does not need focus for them to be activated.
*
* @see KKeyChooser
* @see KKeyDialog
* @see KAction
* @see KKeySequenceWidget
* @see KShortcutsEditor
*/
class KDEUI_EXPORT KGlobalAccel : public QObject
{
@ -62,39 +62,38 @@ public:
static KGlobalAccel *self();
/**
* Returns a list of global shortcuts registered for the shortcut @seq.
* Returns a list of global shortcuts registered for the shortcut @p seq.
*
* If the list contains more that one entry it means the component
* that registered the shortcuts uses global shortcut contexts. All
* returned shortcuts belong to the same component.
* If the list contains more that one entry it means the component that registered the
* shortcuts uses global shortcut contexts. All returned shortcuts belong to the same
* component.
*
* @since 4.2
*/
QList<KGlobalShortcutInfo> getGlobalShortcutsByKey(const QKeySequence &seq);
/**
* Check if the shortcut @seq is available for the @p component. The
* component is only of interest if the current application uses global shortcut
* contexts. In that case a global shortcut by @p component in an inactive
* global shortcut contexts does not block the @p seq for us.
* Check if the shortcut @p seq is available, when checking for conflicts the action specified
* as @p exception is not considered.
*
* @since 4.2
*/
bool isGlobalShortcutAvailable(const QKeySequence &seq,
const QString &component = QString());
const QAction *exception = nullptr);
/**
* Take away the given shortcut from the named action it belongs to.
* This applies to all actions with global shortcuts in any KDE application.
* Take away the given shortcut from the named action it belongs to. This applies to all
* actions with global shortcuts in any KDE application except the @p exception if not null.
*
* @see promptStealShortcutSystemwide()
*/
void stealShortcutSystemwide(const QKeySequence &seq);
void stealShortcutSystemwide(const QKeySequence &seq,
const QAction *exception = nullptr);
/**
* Show a messagebox to inform the user that a global shorcut is already occupied,
* and ask to take it away from its current action(s). This is GUI only, so nothing will
* be actually changed.
* Show a messagebox to inform the user that a global shorcut is already occupied and ask to
* take it away from its current action(s). This is GUI only, so nothing will be actually
* changed.
*
* @see stealShortcutSystemwide()
*

View file

@ -318,18 +318,8 @@ bool KKeySequenceWidgetPrivate::conflictWithGlobalShortcuts(const QKeySequence &
QHash<QKeySequence, QList<KGlobalShortcutInfo> > others;
for (int i = 0; i < keySequence.count(); ++i) {
QKeySequence tmp(keySequence[i]);
if (!kglobalaccel->isGlobalShortcutAvailable(tmp, componentName)) {
if (!kglobalaccel->isGlobalShortcutAvailable(tmp, associatedAction)) {
QList<KGlobalShortcutInfo> globalinfo = kglobalaccel->getGlobalShortcutsByKey(tmp);
if (associatedAction) {
const QString actionObjectName = associatedAction->objectName();
QMutableListIterator<KGlobalShortcutInfo> iter(globalinfo);
while (iter.hasNext()) {
iter.next();
if (iter.value().contextFriendlyName == actionObjectName) {
iter.remove();
}
}
}
if (!globalinfo.isEmpty()) {
others.insert(tmp, globalinfo);
}
@ -346,7 +336,7 @@ bool KKeySequenceWidgetPrivate::conflictWithGlobalShortcuts(const QKeySequence &
// error it just silently fails. So be nice because this is
// most likely the first action that is done in the slot
// listening to keySequenceChanged().
kglobalaccel->stealShortcutSystemwide(keySequence);
kglobalaccel->stealShortcutSystemwide(keySequence, associatedAction);
return false;
}