Re: Konsole confirmation dialog - non-compliant behavior
Tomaz Canabrava <[email protected]> Sat, 13 Dec 2025 21:08:57 +0100
| Newsgroups | gmane.comp.kde.devel.konsole |
|---|---|
| Message-ID | <CACk01_zH_C1REepi8DsKcbPvt6wfW7Cm4NBD1rAmp=qTH6iPiA@mail.gmail.com> |
--000000000000588a860645daf35e Content-Type: text/plain; charset="UTF-8" On Sat, 13 Dec 2025 at 20:15 Cristian S <[email protected]> wrote: > I'm trying to figure out where this bug is coming from. > I'm discussing these particular versions of Konsole and KWidgetsAddons as > published on Debian Snapshots: > > # konsole 20.12.1-1 (sources at > http://snapshot.debian.org/package/konsole/4%3A20.12.1-1/#konsole_4:3a:20.12.1-1 > ) > # kwidgetsaddons 5.78.0-2 (sources at > http://snapshot.debian.org/package/kwidgetsaddons/5.78.0-2/#libkf5widgetsaddons5_5.78.0-2 > ) > this is from 5 years ago, any chance you can update? > The issue I'm trying to fix is with the confirmation dialogs shown for > example by Konsole when trying to close a Konsole window containing a > process or more can updstill running in it. > > This confirmation dialog uses the KMessageBox widget from KWidgetsAddons. > Looking in kwidgetsaddons-5.78.0/src/kmessagebox.h, at line 409, I see > this: > > ==================================== > /** > * Display a Yes/No/Cancel "warning" dialog with a listbox to show > information > * to the user. > * > * @param parent Parent widget. > * @param text Message string. > * @param strlist List of strings to be written in the listbox. If the > * list is empty, it doesn't show any listbox, working > * as warningYesNoCancel. > * @param caption Message box title. The application name is added to > * the title. The default title is i18n("Warning"). > * @param buttonYes The text for the first button. > * The default is KStandardGuiItem::yes(). > * @param buttonNo The text for the second button. > * The default is KStandardGuiItem::no(). > * @param buttonCancel The text for the third button. > * The default is KStandardGuiItem::cancel(). > * @param dontAskAgainName If provided, a checkbox is added with which > * further questions can be turned off. If turned off > * all questions will be automatically answered with the > * last answer (either Yes or No). > * The string is used to lookup and store the setting > * in the applications config file. > * The setting is stored in the "Notification Messages" > group. > * If @p dontAskAgainName starts with a ':' then the setting > * is stored in the global config file. > * @param options see Options > * > * @return @p Yes is returned if the Yes-button is pressed. @p No is > returned > * if the No-button is pressed. @p Cancel is retunred if the > Cancel- > * button is pressed. > * > * To be used for questions "Do you want to save your changes?" > * The text should explain the implication of choosing 'No'. > * > * The default button is "Yes". Pressing "Esc" selects "Cancel" > */ > KWIDGETSADDONS_EXPORT ButtonCode warningYesNoCancelList(QWidget *parent, > const QString &text, > const QStringList &strlist, > const QString &caption = QString(), > const KGuiItem &buttonYes = KStandardGuiItem::yes(), > const KGuiItem &buttonNo = KStandardGuiItem::no(), > const KGuiItem &buttonCancel = KStandardGuiItem::cancel(), > const QString &dontAskAgainName = QString(), > Options options = Notify); > ==================================== > > So the description in the comment clearly says the default button is "Yes". > I take this to mean "the leftmost button having the initial focus". > Also note the order of these buttons is 1="Yes", 2="No", 3="Cancel". > > Now looking in konsole-20.12.1/src/MainWindow.cpp, at line 620, I see > this: > > ==================================== > result = KMessageBox::warningYesNoCancelList(this, > i18ncp("@info", > "There is a process running in this window. " > "Do you still want to quit?", > "There are %1 processes running in this window. " > "Do you still want to quit?", > processesRunning.count()), > processesRunning, > i18nc("@title", "Confirm Close"), > KGuiItem(i18nc("@action:button", > "Close &Window"), > QStringLiteral("window-close")), > KGuiItem(i18nc("@action:button", > "Close Current &Tab"), > QStringLiteral("tab-close")), > KStandardGuiItem::cancel(), > // don't ask again name is wrong but I can't update. > // this is not about tabs anymore. it's about empty tabs *or* splits. > QStringLiteral("CloseAllTabs")); > ==================================== > > So here, the first button is "Close Window" as "Yes", the second is "Close > Current Tab" as "No" and the third is "Cancel" as "Cancel". > So absolutely correct. > > Therefore "Close Window" should be shown as the leftmost button and having > the initial focus. > > Yet, when actually running Konsole, the first (leftmost) button with > initial focus is "Cancel", and "Close Window" is the rightmost button, > which is exactly backwards from the stated behavior of KMessageBox. > > Now my opinion is that this is a bug from KWidgets/KMessageBox and not > from Konsole, and I base this opinion on the fact that this behavior is > common to other KDE programs, for instance Konqueror or KWrite. > I attached to this message screenshots of these confirmation dialogs from > Konsole and Konqueror for reference. > > My question for the readers of this message is: did any of the Konsole > developers notice this backward behavior of the buttons in KMessageBox? > > Has anybody tried to figure out a way to fix this, and, if so, can they > share their findings here? > > I just want to figure out how to get the buttons back in the correct order > with the focus on the first. > Maybe someone can suggest how to do this? > Maybe reverse the order of the buttons in the warningYesNoCancelList() > function call in konsole-20.12.1/src/MainWindow.cpp ? Would that do it? > --000000000000588a860645daf35e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div><br></div><div><br><div class=3D"gmail_quote gmail_quote_container"><d= iv dir=3D"ltr" class=3D"gmail_attr">On Sat, 13 Dec 2025 at 20:15 Cristian S= <<a href=3D"mailto:[email protected]">[email protected]</a>> wrote= :<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.= 8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-l= eft-color:rgb(204,204,204)"> =20 =20 =20 <div bgcolor=3D"#FFFFFF" text=3D"#000000"> I'm trying to figure out where this bug is coming from.<br> I'm discussing these particular versions of Konsole and KWidgetsAddons as published on Debian Snapshots:<br> <br> # =C2=A0=C2=A0 konsole 20.12.1-1 (sources at <a href=3D"http://snapshot.debian.org/package/konsole/4%3A20.12.1-1/#konsol= e_4:3a:20.12.1-1" target=3D"_blank">http://snapshot.debian.org/package/kons= ole/4%3A20.12.1-1/#konsole_4:3a:20.12.1-1</a>)<br> #=C2=A0=C2=A0=C2=A0 kwidgetsaddons 5.78.0-2 (sources at <a href=3D"http://snapshot.debian.org/package/kwidgetsaddons/5.78.0-2/#libk= f5widgetsaddons5_5.78.0-2" target=3D"_blank">http://snapshot.debian.org/pac= kage/kwidgetsaddons/5.78.0-2/#libkf5widgetsaddons5_5.78.0-2</a>)<br> </div></blockquote><div dir=3D"auto"><br></div><div dir=3D"auto">this i= s from 5 years ago, any chance you can update?</div><div dir=3D"auto"><br><= /div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo= rder-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-co= lor:rgb(204,204,204)"><div bgcolor=3D"#FFFFFF" text=3D"#000000" dir=3D"auto= "><br> The issue I'm trying to fix is with the confirmation dialogs shown for example by Konsole when trying to close a Konsole window containing a process or more =C2=A0can updstill running in it.<br> <br> This confirmation dialog uses the KMessageBox widget from KWidgetsAddons.<br> Looking in kwidgetsaddons-5.78.0/src/kmessagebox.h,=C2=A0 at line 409, = I see this:<br> <br> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br> <font face=3D"Courier New, Courier, monospace" style=3D"font-family:&qu= ot;Courier New",Courier,monospace;color:rgb(0,0,0)">/**<br> =C2=A0* Display a Yes/No/Cancel "warning" dialog with a lis= tbox to show information<br> =C2=A0* to the user.<br> =C2=A0*<br> =C2=A0* @param parent=C2=A0 Parent widget.<br> =C2=A0* @param text=C2=A0=C2=A0=C2=A0 Message string.<br> =C2=A0* @param strlist List of strings to be written in the listbox. = If the<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 list is empty, it doesn't show any listb= ox, working<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 as warningYesNoCancel.<br> =C2=A0* @param caption Message box title. The application name is add= ed to<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 the title. The default title is i18n("W= arning").<br> =C2=A0* @param buttonYes The text for the first button.<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The default is KStandardGuiItem:= :yes().<br> =C2=A0* @param buttonNo=C2=A0 The text for the second button.<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The default is KStandardGuiItem:= :no().<br> =C2=A0* @param buttonCancel=C2=A0 The text for the third button.<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The default is KStandardGuiItem:= :cancel().<br> =C2=A0* @param dontAskAgainName If provided, a checkbox is added with which<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 further questions can be turned off. If turn= ed off<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 all questions will be automatically answered with the<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 last answer (either Yes or No).<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The string is used to lookup and store the setting<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 in the applications config file.<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 The setting is stored in the "Notificat= ion Messages" group.<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 If @p dontAskAgainName starts with a ':&= #39; then the setting<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 is stored in the global config file.<br> =C2=A0* @param options=C2=A0 see Options<br> =C2=A0*<br> =C2=A0* @return=C2=A0 @p Yes is returned if the Yes-button is pressed= . @p No is returned<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if the = No-button is pressed. @p Cancel is retunred if the Cancel-<br> =C2=A0*=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 button = is pressed.<br> =C2=A0*<br> =C2=A0* To be used for questions "Do you want to save your chang= es?"<br> =C2=A0* The text should explain the implication of choosing 'No&#= 39;.<br> =C2=A0*<br> =C2=A0* The default button is "Yes". Pressing "Esc&quo= t; selects "Cancel"<br> =C2=A0*/<br> KWIDGETSADDONS_EXPORT ButtonCode warningYesNoCancelList(QWidget *parent,<br> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const QString &text,<b= r> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const QStringList &str= list,<br> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const QString &caption= =3D QString(),<br> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const KGuiItem &button= Yes =3D KStandardGuiItem::yes(),<br> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const KGuiItem &button= No =3D KStandardGuiItem::no(),<br> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const KGuiItem &button= Cancel =3D KStandardGuiItem::cancel(),<br> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 const QString &dontAsk= AgainName =3D QString(),<br> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Options options =3D Notify= );<br> </font>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<font face=3D"Courier New, Courier, monospace" style=3D"font-family:"Courier New",Cour= ier,monospace;color:rgb(0,0,0)"><font face=3D"sans-serif" style=3D"font-fam= ily:sans-serif;color:rgb(0,0,0)"><br> <br> So the description in the comment clearly says the default button is "Yes".<br> I take this to mean "the leftmost button having the initial focus".<br> Also note the order of these buttons is 1=3D"Yes", 2=3D&q= uot;No", 3=3D"Cancel".<br> <br> Now looking in konsole-20.12.1/src/MainWindow.cpp,=C2=A0 at line 62= 0, I see this:<br> <br> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br> <font face=3D"Courier New, Courier, monospace" style=3D"font-family= :"Courier New",Courier,monospace;color:rgb(0,0,0)">result =3D KMessageBox::warningYesNoCancelList(this,<br> =C2=A0=C2=A0=C2=A0 i18ncp("@info",<br> =C2=A0=C2=A0=C2=A0 "There is a process running in this windo= w. "<br> =C2=A0=C2=A0=C2=A0 "Do you still want to quit?",<br> =C2=A0=C2=A0=C2=A0 "There are %1 processes running in this w= indow. "<br> =C2=A0=C2=A0=C2=A0 "Do you still want to quit?",<br> =C2=A0=C2=A0=C2=A0 processesRunning.count()),<br> =C2=A0=C2=A0=C2=A0 processesRunning,<br> =C2=A0=C2=A0=C2=A0 i18nc("@title", "Confirm Close&= quot;),<br> =C2=A0=C2=A0=C2=A0 KGuiItem(i18nc("@action:button",<br> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 "Close &Window&quo= t;),<br> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 QStringLiteral("window= -close")),<br> =C2=A0=C2=A0=C2=A0 KGuiItem(i18nc("@action:button",<br> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 "Close Current &Ta= b"),<br> =C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0=C2=A0 QStringLiteral("tab-cl= ose")),<br> =C2=A0=C2=A0=C2=A0 KStandardGuiItem::cancel(),<br> =C2=A0=C2=A0=C2=A0 // don't ask again name is wrong but I can= 't update.<br> =C2=A0=C2=A0=C2=A0 // this is not about tabs anymore. it's ab= out empty tabs *or* splits.<br> =C2=A0=C2=A0=C2=A0 QStringLiteral("CloseAllTabs"));</fo= nt><br> </font></font><font face=3D"Courier New, Courier, monospace" style=3D= "font-family:"Courier New",Courier,monospace;color:rgb(0,0,0)"><f= ont face=3D"sans-serif" style=3D"font-family:sans-serif;color:rgb(0,0,0)">= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D<br> </font></font><br> So here, the first button is "Close Window" as "Yes"= ;, the second is "Close Current Tab" as "No" and the third is "= Cancel" as "Cancel".<br> So absolutely correct.<br> <br> Therefore "Close Window" should be shown as the leftmost butt= on and having the initial focus.<br> <br> Yet, when actually running Konsole, the first (leftmost) button with initial focus is "Cancel", and "Close Window" is th= e rightmost button, which is exactly backwards from the stated behavior of KMessageBox.<br> <br> Now my opinion is that this is a bug from KWidgets/KMessageBox and not from Konsole, and I base this opinion on the fact that this behavior is common to other KDE programs, for instance Konqueror or KWrite.<br> I attached to this message screenshots of these confirmation dialogs from Konsole and Konqueror for reference.<br> <br> My question for the readers of this message is: did any of the Konsole developers notice this backward behavior of the buttons in KMessageBox?<br> <br> Has anybody tried to figure out a way to fix this, and, if so, can they share their findings here?<br> <br> I just want to figure out how to get the buttons back in the correct order with the focus on the first.<br> Maybe someone can suggest how to do this?<br> Maybe reverse the order of the buttons in the warningYesNoCancelList() function call in <font face=3D"Courier New, Courier, monospace" style=3D"font-family:"Courier New",Cour= ier,monospace;color:rgb(0,0,0)"><font face=3D"sans-serif" style=3D"font-fam= ily:sans-serif;color:rgb(0,0,0)">konsole-20.12.1/src/MainWindow.cpp</font><= /font> ?=C2=A0 Would that do it?<br> </div> </blockquote></div></div> --000000000000588a860645daf35e--