Skip to content

Commit

Permalink
Add a session restore checkbox when quitting the browser.
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAlex94 committed Oct 1, 2023
1 parent 575bb97 commit 80ddad6
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 9 deletions.
2 changes: 1 addition & 1 deletion browser/actors/PromptParent.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ XPCOMUtils.defineLazyPreferenceGetter(
);

XPCOMUtils.defineLazyGetter(lazy, "gTabBrowserLocalization", function () {
return new Localization(["browser/tabbrowser.ftl"], true);
return new Localization(["browser/tabbrowser.ftl", "browser/waterfox.ftl"], true);
});

/**
Expand Down
34 changes: 30 additions & 4 deletions browser/base/content/tabbrowser.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
});
XPCOMUtils.defineLazyGetter(this, "tabLocalization", () => {
return new Localization(
["browser/tabbrowser.ftl", "branding/brand.ftl"],
["browser/tabbrowser.ftl", "branding/brand.ftl", "browser/waterfox.ftl"],
true
);
});
Expand Down Expand Up @@ -3357,26 +3357,40 @@
// default to true: if it were false, we wouldn't get this far
var warnOnClose = { value: true };

let restoreSession;
let startupPref = Services.prefs.getIntPref("browser.startup.page");

// If we are set to anything other than restore session,
// leave its value.
if (startupPref != 3) {
console.log("Value of: " + startupPref);
restoreSession = { value: false };
} else {
console.log("Value of: " + startupPref);
restoreSession = { value: true };
}

// focus the window before prompting.
// this will raise any minimized window, which will
// make it obvious which window the prompt is for and will
// solve the problem of windows "obscuring" the prompt.
// see bug #350299 for more details
window.focus();
const [title, button, checkbox] = this.tabLocalization.formatValuesSync([
const [title, button, checkbox, checkboxLabel2] = this.tabLocalization.formatValuesSync([
{
id: "tabbrowser-confirm-close-tabs-title",
args: { tabCount: tabsToClose },
},
{ id: "tabbrowser-confirm-close-tabs-button" },
{ id: "tabbrowser-confirm-close-tabs-checkbox" },
{ id: "tabbrowser-confirm-session-restore-checkbox" }
]);
let flags =
ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0 +
ps.BUTTON_TITLE_CANCEL * ps.BUTTON_POS_1;
let checkboxLabel =
aCloseTabs == this.closingTabsEnum.ALL ? checkbox : null;
var buttonPressed = ps.confirmEx(
var buttonPressed = ps.confirmEx2(
window,
title,
null,
Expand All @@ -3385,7 +3399,9 @@
null,
null,
checkboxLabel,
warnOnClose
warnOnClose,
checkboxLabel2,
restoreSession
);

Services.telemetry.setEventRecordingEnabled("close_tab_warning", true);
Expand Down Expand Up @@ -3432,6 +3448,16 @@
Services.prefs.setBoolPref(pref, false);
}

if (buttonPressed == 0) {
if (!restoreSession.value) {
if (startupPref === 3) {
Services.prefs.setIntPref("browser.startup.page", 1);
}
} else if (restoreSession.value) {
Services.prefs.setIntPref("browser.startup.page", 3);
}
}

return reallyClose;
},

Expand Down
36 changes: 33 additions & 3 deletions browser/components/BrowserGlue.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3125,6 +3125,18 @@ BrowserGlue.prototype = {
aQuitType = "quit";
}

let restoreSession;
let startupPref = Services.prefs.getIntPref("browser.startup.page");

// If we are set to anything other than restore session,
if (startupPref != 3) {
console.log("Value of: " + startupPref);
restoreSession = { value: false };
} else {
console.log("Value of: " + startupPref);
restoreSession = { value: true };
}

let win = lazy.BrowserWindowTracker.getTopWindow();

// Our prompt for quitting is most important, so replace others.
Expand Down Expand Up @@ -3163,19 +3175,23 @@ BrowserGlue.prototype = {
checkboxLabelId = "tabbrowser-confirm-close-tabs-checkbox";
}

const [title, buttonLabel, checkboxLabel] =
let checkboxLabelId2 = "tabbrowser-confirm-session-restore-checkbox";

const [title, buttonLabel, checkboxLabel, checkboxLabel2] =
win.gBrowser.tabLocalization.formatMessagesSync([
titleId,
buttonLabelId,
checkboxLabelId,
checkboxLabelId2,
]);

let warnOnClose = { value: true };

let flags =
Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1;
// buttonPressed will be 0 for closing, 1 for cancel (don't close/quit)
let buttonPressed = Services.prompt.confirmEx(
let buttonPressed = Services.prompt.confirmEx2(
win,
title.value,
null,
Expand All @@ -3184,7 +3200,9 @@ BrowserGlue.prototype = {
null,
null,
checkboxLabel.value,
warnOnClose
warnOnClose,
checkboxLabel2.value,
restoreSession
);
Services.telemetry.setEventRecordingEnabled("close_tab_warning", true);
let warnCheckbox = warnOnClose.value ? "checked" : "unchecked";
Expand Down Expand Up @@ -3217,6 +3235,18 @@ BrowserGlue.prototype = {
}
}

// If we are set to anything other than restore session,
// leave its value.
if (buttonPressed == 0) {
if (!restoreSession.value) {
if (startupPref === 3) {
Services.prefs.setIntPref("browser.startup.page", 1);
}
} else if (restoreSession.value) {
Services.prefs.setIntPref("browser.startup.page", 3);
}
}

this._quitSource = "unknown";

aCancelQuit.data = buttonPressed != 0;
Expand Down
11 changes: 11 additions & 0 deletions netwerk/base/nsIPrompt.idl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ interface nsIPrompt : nsISupports
in wstring checkMsg,
inout boolean checkValue);

int32_t confirmEx2(in wstring dialogTitle,
in wstring text,
in unsigned long buttonFlags,
in wstring button0Title,
in wstring button1Title,
in wstring button2Title,
in wstring checkMsg,
inout boolean checkValue,
in wstring checkMsg2,
inout boolean checkValue2);

boolean prompt(in wstring dialogTitle,
in wstring text,
inout wstring value,
Expand Down
1 change: 1 addition & 0 deletions toolkit/components/prompts/content/commonDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ function commonDialogOnLoad() {
infoTitle: document.getElementById("infoTitle"),
infoIcon: document.getElementById("infoIcon"),
checkbox: document.getElementById("checkbox"),
checkbox2: document.getElementById("checkbox2"),
checkboxContainer: document.getElementById("checkboxContainer"),
button3: dialog.getButton("extra2"),
button2: dialog.getButton("extra1"),
Expand Down
1 change: 1 addition & 0 deletions toolkit/components/prompts/content/commonDialog.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
<div />
<!-- spacer -->
<xul:checkbox id="checkbox" oncommand="Dialog.onCheckbox()" />
<xul:checkbox id="checkbox2" oncommand="Dialog.onCheckbox2()" />
</div>
</div>
</dialog>
Expand Down
36 changes: 36 additions & 0 deletions toolkit/components/prompts/src/CommonDialog.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ CommonDialog.prototype = {
* @param [commonDialogEl] - Dialog element from commonDialog.xhtml,
* null for TabModalPrompts.
*/
// eslint-disable-next-line complexity
async onLoad(commonDialogEl = null) {
let isEmbedded = !!commonDialogEl?.ownerGlobal.docShell.chromeEventHandler;

Expand Down Expand Up @@ -73,6 +74,28 @@ CommonDialog.prototype = {
this.iconClass = ["question-icon"];
this.soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
break;
case "confirmEx2":
var numButtons2 = 0;
if (this.args.button0Label) {
numButtons2++;
}
if (this.args.button1Label) {
numButtons2++;
}
if (this.args.button2Label) {
numButtons2++;
}
if (this.args.button3Label) {
numButtons2++;
}
if (numButtons2 == 0) {
throw new Error("A dialog with no buttons? Can not haz.");
}
this.numButtons = numButtons2;
this.hasInputField = false;
this.iconClass = ["question-icon"];
this.soundID = Ci.nsISound.EVENT_CONFIRM_DIALOG_OPEN;
break;
case "prompt":
this.numButtons = 2;
this.iconClass = ["question-icon"];
Expand Down Expand Up @@ -190,6 +213,15 @@ CommonDialog.prototype = {
this.ui.checkbox.checked = this.args.checked;
}

let label2 = this.args.checkLabel2;
if (label2) {
// Only show the checkbox if label has a value.
this.ui.checkboxContainer.hidden = false;
this.ui.checkboxContainer.clientTop; // style flush to assure binding is attached
this.setLabelForNode(this.ui.checkbox2, label2);
this.ui.checkbox2.checked = this.args.checked2;
}

// set the icon
let icon = this.ui.infoIcon;
if (icon) {
Expand Down Expand Up @@ -336,6 +368,10 @@ CommonDialog.prototype = {
this.args.checked = this.ui.checkbox.checked;
},

onCheckbox2() {
this.args.checked2 = this.ui.checkbox2.checked;
},

onButton0() {
this.args.promptActive = false;
this.args.ok = true;
Expand Down
88 changes: 88 additions & 0 deletions toolkit/components/prompts/src/Prompter.sys.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,34 @@ Prompter.prototype = {
);
},

confirmEx2(
domWin,
title,
text,
flags,
button0,
button1,
button2,
checkLabel,
checkValue,
checkLabel2,
checkValue2
) {
let p = this.pickPrompter({ domWin });
return p.confirmEx2(
title,
text,
flags,
button0,
button1,
button2,
checkLabel,
checkValue,
checkLabel2,
checkValue2
);
},

/**
* Puts up a dialog with up to 3 buttons and an optional, labeled checkbox.
* @param {BrowsingContext} browsingContext - The browsing context the
Expand Down Expand Up @@ -1467,6 +1495,66 @@ class ModalPrompter {
return args.buttonNumClicked;
}

confirmEx2(
title,
text,
flags,
button0,
button1,
button2,
checkLabel,
checkValue,
checkLabel2,
checkValue2,
extraArgs = {}
) {
if (!title) {
title = InternalPromptUtils.getLocalizedString("Confirm");
}

let args = {
promptType: "confirmEx2",
title,
text,
checkLabel,
checked: this.async ? checkValue : checkValue.value,
checkLabel2,
checked2: this.async ? checkValue2 : checkValue2.value,
ok: false,
buttonNumClicked: 1,
...extraArgs,
};

let [label0, label1, label2, defaultButtonNum, isDelayEnabled] =
InternalPromptUtils.confirmExHelper(flags, button0, button1, button2);

args.defaultButtonNum = defaultButtonNum;
args.enableDelay = isDelayEnabled;

if (label0) {
args.button0Label = label0;
if (label1) {
args.button1Label = label1;
if (label2) {
args.button2Label = label2;
}
}
}

if (this.async) {
return this.openPromptAsync(args, result => ({
checked: !!result.checked,
checked2: !!result.checked2,
buttonNumClicked: result.buttonNumClicked,
}));
}

this.openPromptSync(args);
checkValue.value = args.checked;
checkValue2.value = args.checked2;
return args.buttonNumClicked;
}

nsIPrompt_prompt(title, text, value, checkLabel, checkValue) {
if (!title) {
title = InternalPromptUtils.getLocalizedString("Prompt");
Expand Down
Loading

0 comments on commit 80ddad6

Please sign in to comment.