Skip to content

Commit

Permalink
Add hidden option for preferring windows over tabs
Browse files Browse the repository at this point in the history
See #54.
  • Loading branch information
lydell committed May 21, 2022
1 parent fe80fed commit 8da862a
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 8 deletions.
54 changes: 47 additions & 7 deletions src/background/Program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ import {
TabsPerf,
TimeTracker,
} from "../shared/perf";
import { tweakable, unsignedInt } from "../shared/tweakable";
import { bool, tweakable, unsignedInt } from "../shared/tweakable";

type MessageInfo = {
tabId: number;
Expand Down Expand Up @@ -171,6 +171,11 @@ export const t = {

// How long a matched/activated hint should show as highlighted.
MATCH_HIGHLIGHT_DURATION: unsignedInt(200), // ms

// For people with tiling window managers who exclusively use windows rather
// than tabs. This changes basically everything that deals with tabs to
// instead deal with windows.
PREFER_WINDOWS: bool(false),
};

export const tMeta = tweakable("Background", t);
Expand Down Expand Up @@ -686,7 +691,9 @@ export default class BackgroundProgram {
case "OpenNewTabs":
if (BROWSER === "firefox") {
fireAndForget(
openNewTabs(info.tabId, message.urls),
t.PREFER_WINDOWS.value
? openNewWindows(message.urls)
: openNewTabs(info.tabId, message.urls),
"BackgroundProgram#onWorkerMessage->openNewTabs",
message,
info
Expand Down Expand Up @@ -1195,7 +1202,18 @@ export default class BackgroundProgram {
// downside of using the fake ctrl-click method in Chrome. In fact, there’s
// even an upside to the ctrl-click method: The HTTP Referer header is sent,
// just as if you had clicked the link for real. See: <bugzil.la/1615860>.
if (BROWSER === "chrome") {
if (t.PREFER_WINDOWS.value) {
fireAndForget(
browser.windows
.create({
focused: foreground,
url,
})
.then(() => undefined),
"BackgroundProgram#openNewTab (PREFER_WINDOWS)",
url
);
} else if (BROWSER === "chrome") {
this.sendWorkerMessage(
{
type: "OpenNewTab",
Expand Down Expand Up @@ -2244,10 +2262,17 @@ export default class BackgroundProgram {
async maybeOpenTutorial(): Promise<void> {
const { tutorialShown } = await browser.storage.local.get("tutorialShown");
if (tutorialShown !== true) {
await browser.tabs.create({
active: true,
url: META_TUTORIAL,
});
if (t.PREFER_WINDOWS.value) {
await browser.windows.create({
focused: true,
url: META_TUTORIAL,
});
} else {
await browser.tabs.create({
active: true,
url: META_TUTORIAL,
});
}
await browser.storage.local.set({ tutorialShown: true });
}
}
Expand Down Expand Up @@ -2483,6 +2508,21 @@ async function openNewTabs(tabId: number, urls: Array<string>): Promise<void> {
}
}

// Open a bunch of windows, and then focus the first of them.
async function openNewWindows(urls: Array<string>): Promise<void> {
const newWindows = await Promise.all(
urls.map((url) =>
browser.windows.create({
focused: urls.length === 1,
url,
})
)
);
if (newWindows.length >= 2 && newWindows[0].id !== undefined) {
await browser.windows.update(newWindows[0].id, { focused: true });
}
}

type IconType = "disabled" | "normal";

function getIcons(type: IconType): Record<string, string> {
Expand Down
23 changes: 23 additions & 0 deletions src/options/Tweakable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,29 @@ function TweakableField({
};

switch (value.type) {
case "Bool":
if (defaultValue.type === "Bool") {
return (
<Field
{...fieldProps}
render={({ id }) => (
<label className="Spaced Spaced--center">
<input
type="checkbox"
id={id}
checked={value.value}
onChange={(event) => {
save(fullKey, event.currentTarget.checked);
}}
/>
<span>Enabled</span>
</label>
)}
/>
);
}
break;

case "UnsignedInt":
if (defaultValue.type === "UnsignedInt") {
return (
Expand Down
32 changes: 31 additions & 1 deletion src/shared/tweakable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { array, chain, Decoder, DecoderError, string } from "tiny-decoders";
import {
array,
boolean,
chain,
Decoder,
DecoderError,
string,
} from "tiny-decoders";

import { ElementType } from "./hints";
import {
Expand All @@ -11,6 +18,11 @@ import {
} from "./main";
import { DEBUG_PREFIX } from "./options";

type Bool = {
type: "Bool";
value: boolean;
};

type UnsignedInt = {
type: "UnsignedInt";
value: number;
Expand Down Expand Up @@ -42,6 +54,7 @@ type Regex = {
};

export type TweakableValue =
| Bool
| ElementTypeSet
| Regex
| SelectorString
Expand All @@ -60,6 +73,13 @@ export type TweakableMeta = {
unlisten: () => void;
};

export function bool(value: boolean): Bool {
return {
type: "Bool",
value,
};
}

export function unsignedInt(value: number): UnsignedInt {
return {
type: "UnsignedInt",
Expand Down Expand Up @@ -132,6 +152,16 @@ export function tweakable(
}

switch (original.type) {
case "Bool": {
const decoded = decode(boolean, value);
mapping[key] = {
type: "Bool",
value: decoded,
};
changed[key] = decoded !== original.value;
break;
}

case "UnsignedInt": {
const decoded = decode(UnsignedInt, value);
mapping[key] = {
Expand Down

0 comments on commit 8da862a

Please sign in to comment.