forked from Shinonome/dots-hyprland
media controls: outside click dismissal, no player placeholder
This commit is contained in:
@@ -40,37 +40,34 @@ Scope {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
// Remove unecessary native buses from browsers if there's plasma integration
|
// Remove unecessary native buses from browsers if there's plasma integration
|
||||||
!(hasPlasmaIntegration && player.dbusName.startsWith('org.mpris.MediaPlayer2.firefox')) &&
|
!(hasPlasmaIntegration && player.dbusName.startsWith('org.mpris.MediaPlayer2.firefox')) && !(hasPlasmaIntegration && player.dbusName.startsWith('org.mpris.MediaPlayer2.chromium')) &&
|
||||||
!(hasPlasmaIntegration && player.dbusName.startsWith('org.mpris.MediaPlayer2.chromium')) &&
|
|
||||||
// playerctld just copies other buses and we don't need duplicates
|
// playerctld just copies other buses and we don't need duplicates
|
||||||
!player.dbusName?.startsWith('org.mpris.MediaPlayer2.playerctld') &&
|
!player.dbusName?.startsWith('org.mpris.MediaPlayer2.playerctld') &&
|
||||||
// Non-instance mpd bus
|
// Non-instance mpd bus
|
||||||
!(player.dbusName?.endsWith('.mpd') && !player.dbusName.endsWith('MediaPlayer2.mpd'))
|
!(player.dbusName?.endsWith('.mpd') && !player.dbusName.endsWith('MediaPlayer2.mpd')));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
function filterDuplicatePlayers(players) {
|
function filterDuplicatePlayers(players) {
|
||||||
let filtered = [];
|
let filtered = [];
|
||||||
let used = new Set();
|
let used = new Set();
|
||||||
|
|
||||||
for (let i = 0; i < players.length; ++i) {
|
for (let i = 0; i < players.length; ++i) {
|
||||||
if (used.has(i)) continue;
|
if (used.has(i))
|
||||||
|
continue;
|
||||||
let p1 = players[i];
|
let p1 = players[i];
|
||||||
let group = [i];
|
let group = [i];
|
||||||
|
|
||||||
// Find duplicates by trackTitle prefix
|
// Find duplicates by trackTitle prefix
|
||||||
for (let j = i + 1; j < players.length; ++j) {
|
for (let j = i + 1; j < players.length; ++j) {
|
||||||
let p2 = players[j];
|
let p2 = players[j];
|
||||||
if (p1.trackTitle && p2.trackTitle &&
|
if (p1.trackTitle && p2.trackTitle && (p1.trackTitle.includes(p2.trackTitle) || p2.trackTitle.includes(p1.trackTitle)) || (p1.position - p2.position <= 2 && p1.length - p2.length <= 2)) {
|
||||||
(p1.trackTitle.includes(p2.trackTitle)
|
|
||||||
|| p2.trackTitle.includes(p1.trackTitle))
|
|
||||||
|| (p1.position - p2.position <= 2 && p1.length - p2.length <= 2)) {
|
|
||||||
group.push(j);
|
group.push(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pick the one with non-empty trackArtUrl, or fallback to the first
|
// Pick the one with non-empty trackArtUrl, or fallback to the first
|
||||||
let chosenIdx = group.find(idx => players[idx].trackArtUrl && players[idx].trackArtUrl.length > 0);
|
let chosenIdx = group.find(idx => players[idx].trackArtUrl && players[idx].trackArtUrl.length > 0);
|
||||||
if (chosenIdx === undefined) chosenIdx = group[0];
|
if (chosenIdx === undefined)
|
||||||
|
chosenIdx = group[0];
|
||||||
|
|
||||||
filtered.push(players[chosenIdx]);
|
filtered.push(players[chosenIdx]);
|
||||||
group.forEach(idx => used.add(idx));
|
group.forEach(idx => used.add(idx));
|
||||||
@@ -133,6 +130,16 @@ Scope {
|
|||||||
item: playerColumnLayout
|
item: playerColumnLayout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HyprlandFocusGrab {
|
||||||
|
windows: [mediaControlsRoot]
|
||||||
|
active: mediaControlsLoader.active
|
||||||
|
onCleared: () => {
|
||||||
|
if (!active) {
|
||||||
|
GlobalStates.mediaControlsOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: playerColumnLayout
|
id: playerColumnLayout
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -148,6 +155,43 @@ Scope {
|
|||||||
visualizerPoints: root.visualizerPoints
|
visualizerPoints: root.visualizerPoints
|
||||||
implicitWidth: widgetWidth
|
implicitWidth: widgetWidth
|
||||||
implicitHeight: widgetHeight
|
implicitHeight: widgetHeight
|
||||||
|
radius: root.popupRounding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { // No player placeholder
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: root.meaningfulPlayers.length === 0
|
||||||
|
implicitWidth: placeholderBackground.implicitWidth + Appearance.sizes.elevationMargin
|
||||||
|
implicitHeight: placeholderBackground.implicitHeight + Appearance.sizes.elevationMargin
|
||||||
|
|
||||||
|
StyledRectangularShadow {
|
||||||
|
target: placeholderBackground
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: placeholderBackground
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: Appearance.colors.colLayer0
|
||||||
|
radius: root.popupRounding
|
||||||
|
property real padding: 20
|
||||||
|
implicitWidth: placeholderLayout.implicitWidth + padding * 2
|
||||||
|
implicitHeight: placeholderLayout.implicitHeight + padding * 2
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: placeholderLayout
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: Translation.tr("No active player")
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.large
|
||||||
|
}
|
||||||
|
StyledText {
|
||||||
|
color: Appearance.colors.colSubtext
|
||||||
|
text: Translation.tr("Make sure your player has MPRIS support\nor try turning off duplicate player filtering")
|
||||||
|
font.pixelSize: Appearance.font.pixelSize.small
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,7 +203,8 @@ Scope {
|
|||||||
|
|
||||||
function toggle(): void {
|
function toggle(): void {
|
||||||
mediaControlsLoader.active = !mediaControlsLoader.active;
|
mediaControlsLoader.active = !mediaControlsLoader.active;
|
||||||
if(mediaControlsLoader.active) Notifications.timeoutAll();
|
if (mediaControlsLoader.active)
|
||||||
|
Notifications.timeoutAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
function close(): void {
|
function close(): void {
|
||||||
@@ -196,5 +241,4 @@ Scope {
|
|||||||
GlobalStates.mediaControlsOpen = false;
|
GlobalStates.mediaControlsOpen = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Item { // Player instance
|
|||||||
property list<real> visualizerPoints: []
|
property list<real> visualizerPoints: []
|
||||||
property real maxVisualizerValue: 1000 // Max value in the data points
|
property real maxVisualizerValue: 1000 // Max value in the data points
|
||||||
property int visualizerSmoothing: 2 // Number of points to average for smoothing
|
property int visualizerSmoothing: 2 // Number of points to average for smoothing
|
||||||
|
property real radius
|
||||||
|
|
||||||
component TrackChangeButton: RippleButton {
|
component TrackChangeButton: RippleButton {
|
||||||
implicitWidth: 24
|
implicitWidth: 24
|
||||||
@@ -107,7 +108,7 @@ Item { // Player instance
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Appearance.sizes.elevationMargin
|
anchors.margins: Appearance.sizes.elevationMargin
|
||||||
color: blendedColors.colLayer0
|
color: blendedColors.colLayer0
|
||||||
radius: root.popupRounding
|
radius: playerController.radius
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: OpacityMask {
|
layer.effect: OpacityMask {
|
||||||
@@ -141,7 +142,7 @@ Item { // Player instance
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: ColorUtils.transparentize(blendedColors.colLayer0, 0.3)
|
color: ColorUtils.transparentize(blendedColors.colLayer0, 0.3)
|
||||||
radius: root.popupRounding
|
radius: playerController.radius
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user