Commit a4137ac8 authored by Harald Sitter's avatar Harald Sitter 🏳️‍🌈
Browse files

when deleting an entry, also delete the widgets

previously what would happen is that KCMHotkeys::currentChanged would
run, find the new index (-1,-1) now invalid and show the global settings
instead. this however left the simple_action's underlying widgets still
sitting around referring to the previous index AND holding a dangling
trigger point that would eventually crash when the simple_action would
be poked by anything

instead force unset the internal state of the simple_action when showing
the global settings.

FIXED-IN: 5.23.5
BUG: 443656


(cherry picked from commit 97f9339f)
parent a53c4fe4
......@@ -120,6 +120,9 @@ void KCMHotkeys::currentChanged(const QModelIndex &pCurrent, const QModelIndex &
}
if (!current.isValid()) {
if (previous.isValid()) { // throw away old widget and stuff lest we have dangling pointers https://bugs.kde.org/show_bug.cgi?id=443656
d->simple_action->unsetActionData();
}
return showGlobalSettings();
}
......
......@@ -60,14 +60,22 @@ void SimpleActionDataWidget::doCopyToObject()
}
}
void SimpleActionDataWidget::setActionData(KHotKeys::SimpleActionData *pData)
void SimpleActionDataWidget::unsetActionData()
{
_data = pData;
_data = nullptr;
// Now go and work on the trigger
delete currentTrigger;
currentTrigger = nullptr;
delete currentAction;
currentAction = nullptr;
}
void SimpleActionDataWidget::setActionData(KHotKeys::SimpleActionData *pData)
{
unsetActionData();
_data = pData;
if (KHotKeys::Trigger *trg = data()->trigger()) {
switch (trg->type()) {
case KHotKeys::Trigger::ShortcutTriggerType:
......@@ -95,10 +103,6 @@ void SimpleActionDataWidget::setActionData(KHotKeys::SimpleActionData *pData)
extend(currentTrigger, i18n("Trigger"));
}
// Now go and work on the action
delete currentAction;
currentAction = nullptr;
if (KHotKeys::Action *act = data()->action()) {
switch (act->type()) {
case KHotKeys::Action::MenuEntryActionType:
......
......@@ -32,6 +32,9 @@ public:
*/
void setActionData(KHotKeys::SimpleActionData *action);
/// Throws away the held widgets and state.
void unsetActionData();
KHotKeys::SimpleActionData *data()
{
return static_cast<KHotKeys::SimpleActionData *>(_data);
......
......@@ -10,6 +10,14 @@ TriggerWidgetBase::TriggerWidgetBase(KHotKeys::Trigger *trigger, QWidget *parent
: HotkeysWidgetIFace(parent)
, _trigger(trigger)
{
// Safety net to catch use-after-free. The triggers are not held or managed by us nor our parent.
// Makes them easier to spot, unlike https://bugs.kde.org/show_bug.cgi?id=443656
auto qObject = dynamic_cast<QObject *>(trigger);
if (qObject) {
connect(qObject, &QObject::destroyed, this, [this] {
_trigger = nullptr;
});
}
}
TriggerWidgetBase::~TriggerWidgetBase()
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment