summaryrefslogtreecommitdiff
path: root/application
diff options
context:
space:
mode:
authorFranklinDM <mrmineshafter17@gmail.com>2018-11-16 20:59:11 +0800
committerFranklinDM <mrmineshafter17@gmail.com>2018-11-16 20:59:11 +0800
commitbecd71a8600c7229f765d8eda21c1843c4f4adf1 (patch)
tree71cd3aa344b8b966dc158774ab94a367fa65f3de /application
parentc94825c861795cc2bb0b98483143f277eb3f5060 (diff)
downloaduxp-becd71a8600c7229f765d8eda21c1843c4f4adf1.tar.gz
Issue #638 - Part 1: Provide a visual indicator for muting/unmuting tabs
Diffstat (limited to 'application')
-rw-r--r--application/palemoon/app/profile/palemoon.js4
-rw-r--r--application/palemoon/base/content/tabbrowser.xml140
-rw-r--r--application/palemoon/themes/linux/browser.css73
-rw-r--r--application/palemoon/themes/linux/jar.mn2
-rw-r--r--application/palemoon/themes/osx/browser.css73
-rw-r--r--application/palemoon/themes/osx/jar.mn2
-rw-r--r--application/palemoon/themes/shared/tabbrowser/tab-audio-small.svg85
-rw-r--r--application/palemoon/themes/shared/tabbrowser/tab-audio.svg86
-rw-r--r--application/palemoon/themes/windows/browser.css72
-rw-r--r--application/palemoon/themes/windows/jar.mn2
10 files changed, 538 insertions, 1 deletions
diff --git a/application/palemoon/app/profile/palemoon.js b/application/palemoon/app/profile/palemoon.js
index 15accd1467..e53b1693b7 100644
--- a/application/palemoon/app/profile/palemoon.js
+++ b/application/palemoon/app/profile/palemoon.js
@@ -463,6 +463,10 @@ pref("browser.tabs.closeButtons", 1);
// false return to the adjacent tab (old default)
pref("browser.tabs.selectOwnerOnClose", true);
+pref("browser.tabs.showAudioPlayingIcon", true);
+// This should match Chromium's audio indicator delay.
+pref("browser.tabs.delayHidingAudioPlayingIconMS", 3000);
+
pref("browser.allTabs.previews", true);
pref("browser.ctrlTab.previews", true);
pref("browser.ctrlTab.recentlyUsedLimit", 7);
diff --git a/application/palemoon/base/content/tabbrowser.xml b/application/palemoon/base/content/tabbrowser.xml
index dc6cb0a9d1..0a2a1c3f5f 100644
--- a/application/palemoon/base/content/tabbrowser.xml
+++ b/application/palemoon/base/content/tabbrowser.xml
@@ -3347,6 +3347,78 @@
tab.setAttribute("titlechanged", "true");
]]>
</handler>
+ <handler event="DOMAudioPlaybackStarted">
+ <![CDATA[
+ var tab = getTabFromAudioEvent(event)
+ if (!tab) {
+ return;
+ }
+
+ clearTimeout(tab._soundPlayingAttrRemovalTimer);
+ tab._soundPlayingAttrRemovalTimer = 0;
+
+ let modifiedAttrs = [];
+ if (tab.hasAttribute("soundplaying-scheduledremoval")) {
+ tab.removeAttribute("soundplaying-scheduledremoval");
+ modifiedAttrs.push("soundplaying-scheduledremoval");
+ }
+
+ if (!tab.hasAttribute("soundplaying")) {
+ tab.setAttribute("soundplaying", true);
+ modifiedAttrs.push("soundplaying");
+ }
+
+ this._tabAttrModified(tab, modifiedAttrs);
+ ]]>
+ </handler>
+ <handler event="DOMAudioPlaybackStopped">
+ <![CDATA[
+ var tab = getTabFromAudioEvent(event)
+ if (!tab) {
+ return;
+ }
+
+ if (tab.hasAttribute("soundplaying")) {
+ let removalDelay = Services.prefs.getIntPref("browser.tabs.delayHidingAudioPlayingIconMS");
+
+ tab.style.setProperty("--soundplaying-removal-delay", `${removalDelay - 300}ms`);
+ tab.setAttribute("soundplaying-scheduledremoval", "true");
+ this._tabAttrModified(tab, ["soundplaying-scheduledremoval"]);
+
+ tab._soundPlayingAttrRemovalTimer = setTimeout(() => {
+ tab.removeAttribute("soundplaying-scheduledremoval");
+ tab.removeAttribute("soundplaying");
+ this._tabAttrModified(tab, ["soundplaying", "soundplaying-scheduledremoval"]);
+ }, removalDelay);
+ }
+ ]]>
+ </handler>
+ <handler event="DOMAudioPlaybackBlockStarted">
+ <![CDATA[
+ var tab = getTabFromAudioEvent(event)
+ if (!tab) {
+ return;
+ }
+
+ if (!tab.hasAttribute("blocked")) {
+ tab.setAttribute("blocked", true);
+ this._tabAttrModified(tab, ["blocked"]);
+ }
+ ]]>
+ </handler>
+ <handler event="DOMAudioPlaybackBlockStopped">
+ <![CDATA[
+ var tab = getTabFromAudioEvent(event)
+ if (!tab) {
+ return;
+ }
+
+ if (tab.hasAttribute("blocked")) {
+ tab.removeAttribute("blocked");
+ this._tabAttrModified(tab, ["blocked"]);
+ }
+ ]]>
+ </handler>
</handlers>
</binding>
@@ -4762,6 +4834,10 @@
xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected"
class="tab-text tab-label"
role="presentation"/>
+ <xul:image xbl:inherits="soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected=visuallyselected"
+ anonid="soundplaying-icon"
+ class="tab-icon-sound"
+ role="presentation"/>
<xul:toolbarbutton anonid="close-button"
xbl:inherits="fadein,pinned,selected"
class="tab-close-button close-icon"/>
@@ -4782,9 +4858,59 @@
</property>
<field name="mOverCloseButton">false</field>
+ <property name="_overPlayingIcon" readonly="true">
+ <getter><![CDATA[
+ let iconVisible = this.hasAttribute("soundplaying") ||
+ this.hasAttribute("muted") ||
+ this.hasAttribute("blocked");
+ let soundPlayingIcon =
+ document.getAnonymousElementByAttribute(this, "anonid", "soundplaying-icon");
+ let overlayIcon =
+ document.getAnonymousElementByAttribute(this, "anonid", "overlay-icon");
+
+ return soundPlayingIcon && soundPlayingIcon.matches(":hover") ||
+ (overlayIcon && overlayIcon.matches(":hover") && iconVisible);
+ ]]></getter>
+ </property>
<field name="mCorrespondingMenuitem">null</field>
<field name="closing">false</field>
<field name="lastAccessed">0</field>
+
+ <method name="toggleMuteAudio">
+ <parameter name="aMuteReason"/>
+ <body>
+ <![CDATA[
+ let tabContainer = this.parentNode;
+ let browser = this.linkedBrowser;
+ let modifiedAttrs = [];
+ if (browser.audioBlocked) {
+ this.removeAttribute("blocked");
+ modifiedAttrs.push("blocked");
+
+ // We don't want sound icon flickering between "blocked", "none" and
+ // "sound-playing", here adding the "soundplaying" is to keep the
+ // transition smoothly.
+ if (!this.hasAttribute("soundplaying")) {
+ this.setAttribute("soundplaying", true);
+ modifiedAttrs.push("soundplaying");
+ }
+
+ browser.resumeMedia();
+ } else {
+ if (browser.audioMuted) {
+ browser.unmute();
+ this.removeAttribute("muted");
+ } else {
+ browser.mute();
+ this.setAttribute("muted", "true");
+ }
+ this.muteReason = aMuteReason || null;
+ modifiedAttrs.push("muted");
+ }
+ tabContainer.tabbrowser._tabAttrModified(this, modifiedAttrs);
+ ]]>
+ </body>
+ </method>
</implementation>
<handlers>
@@ -4843,7 +4969,8 @@
if (this.selected) {
this.style.MozUserFocus = 'ignore';
this.clientTop; // just using this to flush style updates
- } else if (this.mOverCloseButton) {
+ } else if (this.mOverCloseButton ||
+ this._overPlayingIcon) {
// Prevent tabbox.xml from selecting the tab.
event.stopPropagation();
}
@@ -4852,6 +4979,17 @@
<handler event="mouseup">
this.style.MozUserFocus = '';
</handler>
+ <handler event="click">
+ <![CDATA[
+ if (event.button != 0) {
+ return;
+ }
+
+ if (this._overPlayingIcon) {
+ this.toggleMuteAudio();
+ }
+ ]]>
+ </handler>
</handlers>
</binding>
diff --git a/application/palemoon/themes/linux/browser.css b/application/palemoon/themes/linux/browser.css
index c6587babcc..cf48dc8196 100644
--- a/application/palemoon/themes/linux/browser.css
+++ b/application/palemoon/themes/linux/browser.css
@@ -1758,6 +1758,79 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
-moz-margin-end: -1px;
}
+/* Tab sound indicator */
+.tab-icon-sound {
+ -moz-margin-start: 4px;
+ width: 16px;
+ height: 16px;
+ padding: 0;
+}
+
+.tab-icon-sound:not(:-moz-any([soundplaying],[muted])),
+.tab-icon-sound[pinned] {
+ display: none;
+}
+
+.tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio");
+}
+
+.tab-icon-sound[soundplaying]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-hover");
+}
+
+.tab-icon-sound[soundplaying]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-pressed");
+}
+
+.tab-icon-sound[muted],
+.tab-icon-sound[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted");
+}
+
+.tab-icon-sound[muted]:hover,
+.tab-icon-sound[blocked]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-hover");
+}
+
+.tab-icon-sound[muted]:hover:active,
+.tab-icon-sound[blocked]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-pressed");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark-hover");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark-pressed");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked],
+#TabsToolbar[brighttext] .tab-icon-sound[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked]:hover,
+#TabsToolbar[brighttext] .tab-icon-sound[muted]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark-hover");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked]:hover:active,
+#TabsToolbar[brighttext] .tab-icon-sound[muted]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark-pressed");
+}
+
+.tab-icon-sound[soundplaying-scheduledremoval]:not([muted]):not(:hover),
+.tab-icon-overlay[soundplaying-scheduledremoval]:not([muted]):not(:hover) {
+ transition: opacity .3s linear var(--soundplaying-removal-delay);
+ opacity: 0;
+}
+
/* Tabstrip new tab button */
.tabs-newtab-button,
#TabsToolbar > #new-tab-button ,
diff --git a/application/palemoon/themes/linux/jar.mn b/application/palemoon/themes/linux/jar.mn
index 8b2e9dc77e..8cb6878e8b 100644
--- a/application/palemoon/themes/linux/jar.mn
+++ b/application/palemoon/themes/linux/jar.mn
@@ -123,6 +123,8 @@ browser.jar:
skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png)
skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
+ skin/classic/browser/tabbrowser/tab-audio.svg (../shared/tabbrowser/tab-audio.svg)
+ skin/classic/browser/tabbrowser/tab-audio-small.svg (../shared/tabbrowser/tab-audio-small.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16-throbber.png
skin/classic/browser/sync-16.png
diff --git a/application/palemoon/themes/osx/browser.css b/application/palemoon/themes/osx/browser.css
index a915af3a3c..d9b7d12715 100644
--- a/application/palemoon/themes/osx/browser.css
+++ b/application/palemoon/themes/osx/browser.css
@@ -1821,6 +1821,79 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
}
}
+/* Tab sound indicator */
+.tab-icon-sound {
+ -moz-margin-start: 4px;
+ width: 16px;
+ height: 16px;
+ padding: 0;
+}
+
+.tab-icon-sound:not(:-moz-any([soundplaying],[muted])),
+.tab-icon-sound[pinned] {
+ display: none;
+}
+
+.tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio");
+}
+
+.tab-icon-sound[soundplaying]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-hover");
+}
+
+.tab-icon-sound[soundplaying]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-pressed");
+}
+
+.tab-icon-sound[muted],
+.tab-icon-sound[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted");
+}
+
+.tab-icon-sound[muted]:hover,
+.tab-icon-sound[blocked]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-hover");
+}
+
+.tab-icon-sound[muted]:hover:active,
+.tab-icon-sound[blocked]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-pressed");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark-hover");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark-pressed");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked],
+#TabsToolbar[brighttext] .tab-icon-sound[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked]:hover,
+#TabsToolbar[brighttext] .tab-icon-sound[muted]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark-hover");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked]:hover:active,
+#TabsToolbar[brighttext] .tab-icon-sound[muted]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark-pressed");
+}
+
+.tab-icon-sound[soundplaying-scheduledremoval]:not([muted]):not(:hover),
+.tab-icon-overlay[soundplaying-scheduledremoval]:not([muted]):not(:hover) {
+ transition: opacity .3s linear var(--soundplaying-removal-delay);
+ opacity: 0;
+}
+
/* Tab scrollbox arrow, tabstrip new tab and all-tabs buttons */
.tabbrowser-arrowscrollbox > .scrollbutton-up,
diff --git a/application/palemoon/themes/osx/jar.mn b/application/palemoon/themes/osx/jar.mn
index a665639894..1a11d0a30d 100644
--- a/application/palemoon/themes/osx/jar.mn
+++ b/application/palemoon/themes/osx/jar.mn
@@ -166,6 +166,8 @@ browser.jar:
skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
+ skin/classic/browser/tabbrowser/tab-audio.svg (../shared/tabbrowser/tab-audio.svg)
+ skin/classic/browser/tabbrowser/tab-audio-small.svg (../shared/tabbrowser/tab-audio-small.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png
skin/classic/browser/sync-16.png
diff --git a/application/palemoon/themes/shared/tabbrowser/tab-audio-small.svg b/application/palemoon/themes/shared/tabbrowser/tab-audio-small.svg
new file mode 100644
index 0000000000..da4ad3ef9b
--- /dev/null
+++ b/application/palemoon/themes/shared/tabbrowser/tab-audio-small.svg
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+ <style>
+ use:not(:target) {
+ display: none;
+ }
+ .icon {
+ fill: #4d4d4d;
+ }
+ .icon.hover {
+ fill: #333333;
+ }
+ .icon.pressed {
+ fill: #000;
+ }
+ .icon.dark {
+ fill: #ccc;
+ }
+ .icon.dark.hover {
+ fill: #b2b2b2;
+ }
+ .icon.dark.pressed {
+ fill: #fff;
+ }
+ .muted {
+ opacity: .7;
+ stroke: #4d4d4d;
+ stroke-width: 0;
+ }
+ .muted.hover {
+ opacity: .85;
+ stroke: #333333;
+ }
+ .muted.pressed {
+ opacity: 1;
+ stroke: #000;
+ }
+ .muted.dark {
+ stroke: #ccc;
+ }
+ .muted.dark.hover {
+ stroke: #b2b2b2;
+ }
+ .muted.dark.pressed {
+ stroke: #fff;
+ }
+ </style>
+ <defs>
+ <clipPath id="clip-wave">
+ <path d="M 11,7 l 3,-8 l 2,0 l 0,18 l -2,0 l -3,-8 z" />
+ </clipPath>
+ <mask id="disabled-cutout">
+ <rect width="16" height="16" fill="#fff" />
+ <line x1="4" y1="14" x2="14" y2="4" stroke="#000" stroke-width="2" />
+ </mask>
+ <g id="shape-tab-audio">
+ <rect x="3" y="6" width="5" height="4" rx="1" ry="1" />
+ <polygon points="5.5,6.5 9,3 9,13 5.5,9.5" />
+ <path d="M 10,6.5 a 1.5 1.5 0 0,1 0,3 z" />
+ <path d="M 10,4 a 4 4 0 0,1 0,8 l 0,-1 a 3 3 0 0,0 0,-6 z" clip-path="url(#clip-wave)" />
+ </g>
+ <g id="shape-tab-audio-muted">
+ <g mask="url(#disabled-cutout)">
+ <rect x="4" y="6" width="5" height="4" rx="1" ry="1" />
+ <polygon points="6.5,6.5 10,3 10,13 6.5,9.5" />
+ </g>
+ <line x1="3" y1="14" x2="13" y2="4" stroke-width="1.5" />
+ </g>
+ </defs>
+ <use id="tab-audio" class="icon" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-hover" class="icon hover" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-pressed" class="icon pressed" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-muted" class="icon muted" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-hover" class="icon muted hover" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-pressed" class="icon muted pressed" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-dark" class="icon dark" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-dark-hover" class="icon hover dark" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-dark-pressed" class="icon pressed dark" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-muted-dark" class="icon muted dark" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-dark-hover" class="icon muted hover dark" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-dark-pressed" class="icon muted pressed dark" xlink:href="#shape-tab-audio-muted" />
+</svg> \ No newline at end of file
diff --git a/application/palemoon/themes/shared/tabbrowser/tab-audio.svg b/application/palemoon/themes/shared/tabbrowser/tab-audio.svg
new file mode 100644
index 0000000000..1949c0595f
--- /dev/null
+++ b/application/palemoon/themes/shared/tabbrowser/tab-audio.svg
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
+ <style>
+ use:not(:target) {
+ display: none;
+ }
+ .icon {
+ fill: #666;
+ }
+ .icon.hover {
+ fill: #4d4d4d;
+ }
+ .icon.pressed {
+ fill: #000;
+ }
+ .icon.dark {
+ fill: #999;
+ }
+ .icon.dark.hover {
+ fill: #b2b2b2;
+ }
+ .icon.dark.pressed {
+ fill: #fff;
+ }
+ .muted {
+ opacity: .7;
+ stroke: #666;
+ stroke-width: 0;
+ }
+ .muted.hover {
+ opacity: .85;
+ stroke: #4d4d4d;
+ }
+ .muted.pressed {
+ opacity: 1;
+ stroke: #000;
+ }
+ .muted.dark {
+ stroke: #999;
+ }
+ .muted.dark.hover {
+ stroke: #b2b2b2;
+ }
+ .muted.dark.pressed {
+ stroke: #fff;
+ }
+ </style>
+ <defs>
+ <clipPath id="clip-wave">
+ <path d="M 10,7 l 3,-8 l 2,0 l 0,18 l -2,0 l -3,-8 z" />
+ </clipPath>
+ <mask id="disabled-cutout">
+ <rect width="16" height="16" fill="#fff" />
+ <line x1="4" y1="14" x2="14" y2="4" stroke="#000" stroke-width="2" />
+ </mask>
+ <g id="shape-tab-audio">
+ <rect x="2" y="5" width="6" height="6" rx="2" ry="2" />
+ <polygon points="4,6 9,2 9,14 4,10" />
+ <path d="M 10,7 a 1 1 0 0,1 0,2 z" />
+ <path d="M 10,5 a 3 3 0 0,1 0,6 l 0,-1 a 2 2 0 0,0 0,-4 z" clip-path="url(#clip-wave)" />
+ <path d="M 10,3 a 5 5 0 0,1 0,10 l 0,-1 a 4 4 0 0,0 0,-8 z" clip-path="url(#clip-wave)" />
+ </g>
+ <g id="shape-tab-audio-muted">
+ <g mask="url(#disabled-cutout)">
+ <rect x="3" y="5" width="6" height="6" rx="2" ry="2" />
+ <polygon points="5,6 10,2 10,14 5,10" />
+ </g>
+ <line x1="2" y1="13" x2="14" y2="3" stroke-width="1.5" />
+ </g>
+ </defs>
+ <use id="tab-audio" class="icon" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-hover" class="icon hover" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-pressed" class="icon pressed" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-muted" class="icon muted" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-hover" class="icon muted hover" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-pressed" class="icon muted pressed" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-dark" class="icon dark" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-dark-hover" class="icon hover dark" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-dark-pressed" class="icon pressed dark" xlink:href="#shape-tab-audio"/>
+ <use id="tab-audio-muted-dark" class="icon muted dark" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-dark-hover" class="icon muted hover dark" xlink:href="#shape-tab-audio-muted" />
+ <use id="tab-audio-muted-dark-pressed" class="icon muted pressed dark" xlink:href="#shape-tab-audio-muted" />
+</svg> \ No newline at end of file
diff --git a/application/palemoon/themes/windows/browser.css b/application/palemoon/themes/windows/browser.css
index 45f0e066c2..aa7afa7a61 100644
--- a/application/palemoon/themes/windows/browser.css
+++ b/application/palemoon/themes/windows/browser.css
@@ -2018,6 +2018,78 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
list-style-image: url("chrome://global/skin/icons/close-inverted.svg");
}
+/* Tab sound indicator */
+.tab-icon-sound {
+ -moz-margin-start: 4px;
+ width: 16px;
+ height: 16px;
+ padding: 0;
+}
+
+.tab-icon-sound:not(:-moz-any([soundplaying],[muted])),
+.tab-icon-sound[pinned] {
+ display: none;
+}
+
+.tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio");
+}
+
+.tab-icon-sound[soundplaying]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-hover");
+}
+
+.tab-icon-sound[soundplaying]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-pressed");
+}
+
+.tab-icon-sound[muted],
+.tab-icon-sound[blocked] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted");
+}
+
+.tab-icon-sound[muted]:hover,
+.tab-icon-sound[blocked]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-hover");
+}
+
+.tab-icon-sound[muted]:hover:active,
+.tab-icon-sound[blocked]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-pressed");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark-hover");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[soundplaying]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-dark-pressed");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked],
+#TabsToolbar[brighttext] .tab-icon-sound[muted] {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked]:hover,
+#TabsToolbar[brighttext] .tab-icon-sound[muted]:hover {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark-hover");
+}
+
+#TabsToolbar[brighttext] .tab-icon-sound[blocked]:hover:active,
+#TabsToolbar[brighttext] .tab-icon-sound[muted]:hover:active {
+ list-style-image: url("chrome://browser/skin/tabbrowser/tab-audio.svg#tab-audio-muted-dark-pressed");
+}
+
+.tab-icon-sound[soundplaying-scheduledremoval]:not([muted]):not(:hover) {
+ transition: opacity .3s linear var(--soundplaying-removal-delay);
+ opacity: 0;
+}
+
/* Tab scrollbox arrow, tabstrip new tab and all-tabs buttons */
.tabbrowser-arrowscrollbox > .scrollbutton-up,
diff --git a/application/palemoon/themes/windows/jar.mn b/application/palemoon/themes/windows/jar.mn
index 0a4342d403..984de5384c 100644
--- a/application/palemoon/themes/windows/jar.mn
+++ b/application/palemoon/themes/windows/jar.mn
@@ -151,6 +151,8 @@ browser.jar:
skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
+ skin/classic/browser/tabbrowser/tab-audio.svg (../shared/tabbrowser/tab-audio.svg)
+ skin/classic/browser/tabbrowser/tab-audio-small.svg (../shared/tabbrowser/tab-audio-small.svg)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png
skin/classic/browser/sync-16.png