prompt to kill kded6, mako, dunst (conflicting stuff)

This commit is contained in:
end-4 2025-08-16 21:00:56 +07:00
parent fcab19c392
commit c745615a2a
5 changed files with 254 additions and 4 deletions

View file

@ -0,0 +1,195 @@
//@ pragma UseQApplication
//@ pragma Env QS_NO_RELOAD_POPUP=1
//@ pragma Env QT_QUICK_CONTROLS_STYLE=Basic
//@ pragma Env QT_QUICK_FLICKABLE_WHEEL_DECELERATION=10000
// Adjust this to make the app smaller or larger
//@ pragma Env QT_SCALE_FACTOR=1
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Window
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
ApplicationWindow {
id: root
property int conflictCount: 0
onConflictCountChanged: {
if (conflictCount === 0) {
root.close();
}
}
property real contentPadding: 8
visible: true
onClosing: {
Qt.quit()
}
title: Translation.tr("Shell conflicts killer")
Component.onCompleted: {
Config.ready // Just read to force init
MaterialThemeLoader.reapplyTheme();
}
minimumWidth: 400
minimumHeight: 300
maximumWidth: 400
maximumHeight: 300
width: 400
height: 300
color: Appearance.m3colors.m3background
component ConflictingProgramGroup: ColumnLayout {
id: conflictGroup
required property list<string> programs
required property string description
visible: false
onVisibleChanged: {
conflictCount += visible ? 1 : -1
}
signal alwaysSelected()
Process {
running: true
command: ["pidof", ...conflictGroup.programs]
onExited: (exitCode, exitStatus) => {
if (exitCode === 0) {
conflictGroup.visible = true
}
}
}
StyledText {
text: conflictGroup.programs.join(", ")
font.pixelSize: Appearance.font.pixelSize.normal
}
StyledText {
font {
pixelSize: Appearance.font.pixelSize.smaller
italic: true
}
text: conflictGroup.description
color: Appearance.colors.colSubtext
}
RowLayout {
Layout.alignment: Qt.AlignRight
RippleButton {
colBackground: Appearance.colors.colLayer2
contentItem: StyledText {
text: Translation.tr("Always")
}
onClicked: {
Quickshell.execDetached(["killall", ...conflictGroup.programs])
conflictGroup.visible = false
conflictGroup.alwaysSelected()
}
}
RippleButton {
colBackground: Appearance.colors.colLayer2
contentItem: StyledText {
text: Translation.tr("Yes")
}
onClicked: {
Quickshell.execDetached(["killall", ...conflictGroup.programs])
conflictGroup.visible = false
}
}
RippleButton {
colBackground: Appearance.colors.colLayer2
contentItem: StyledText {
text: Translation.tr("No")
}
onClicked: conflictGroup.visible = false
}
}
}
ColumnLayout {
anchors {
fill: parent
margins: contentPadding
}
Item {
// Titlebar
visible: Config.options?.windows.showTitlebar
Layout.fillWidth: true
implicitHeight: Math.max(welcomeText.implicitHeight, windowControlsRow.implicitHeight)
StyledText {
id: welcomeText
anchors {
left: Config.options.windows.centerTitle ? undefined : parent.left
horizontalCenter: Config.options.windows.centerTitle ? parent.horizontalCenter : undefined
verticalCenter: parent.verticalCenter
leftMargin: 12
}
color: Appearance.colors.colOnLayer0
text: Translation.tr("Kill conflicting programs?")
font.pixelSize: Appearance.font.pixelSize.title
font.family: Appearance.font.family.title
}
RowLayout { // Window controls row
id: windowControlsRow
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
RippleButton {
buttonRadius: Appearance.rounding.full
implicitWidth: 35
implicitHeight: 35
onClicked: root.close()
contentItem: MaterialSymbol {
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
text: "close"
iconSize: 20
}
}
}
}
Rectangle {
// Content container
color: Appearance.m3colors.m3surfaceContainerLow
radius: Appearance.rounding.windowRounding - root.contentPadding
implicitHeight: contentColumn.implicitHeight
implicitWidth: contentColumn.implicitWidth
Layout.fillWidth: true
Layout.fillHeight: true
ColumnLayout {
id: contentColumn
anchors.fill: parent
spacing: 12
ConflictingProgramGroup {
id: kded6Group
Layout.alignment: Qt.AlignHCenter
Layout.fillHeight: false
programs: ["kded6"]
description: Translation.tr("Conflicts with the shell's system tray implementation")
onAlwaysSelected: Config.options.conflictKiller.autoKillTrays = true
}
ConflictingProgramGroup {
id: notificationDaemons
Layout.alignment: Qt.AlignHCenter
Layout.fillHeight: false
programs: ["mako", "dunst"]
description: Translation.tr("Conflicts with the shell's notification implementation")
onAlwaysSelected: Config.options.conflictKiller.autoKillNotificationDaemons = true
}
}
}
}
}

View file

@ -183,6 +183,11 @@ Singleton {
property int suspend: 3
}
property JsonObject conflictKiller: JsonObject {
property bool autoKillNotificationDaemons: false
property bool autoKillTrays: false
}
property JsonObject dock: JsonObject {
property bool enable: false
property bool monochromeIcons: true

View file

@ -133,7 +133,7 @@ Button {
background: Rectangle {
id: buttonBackground
radius: root.buttonEffectiveRadius
implicitHeight: 50
implicitHeight: 30
color: root.buttonColor
Behavior on color {

View file

@ -0,0 +1,49 @@
pragma Singleton
import qs
import qs.modules.common
import qs.modules.common.functions
import QtQuick
import Quickshell
import Quickshell.Io
Singleton {
id: root
property string killDialogQmlPath: FileUtils.trimFileProtocol(Quickshell.shellPath("killDialog.qml"))
function load() {
// dummy to force init
}
Connections {
target: Config
function onReadyChanged() {
if (Config.ready) checkConflictsProc.running = true
}
}
Process {
id: checkConflictsProc
command: ["bash", "-c", `echo "$(pidof kded6);$(pidof mako dunst)"`]
stdout: StdioCollector {
onStreamFinished: {
const output = this.text;
const conflictingTrays = output.split(";")[0].trim().length > 0;
const conflictingNotifications = output.split(";")[1].trim().length > 0;
var openDialog = false;
if (conflictingTrays) {
if (!Config.options.conflictKiller.autoKillTrays) openDialog = true;
else Quickshell.execDetached(["killall", "kded6"])
}
if (conflictingNotifications) {
if (!Config.options.conflictKiller.autoKillNotificationDaemons) openDialog = true;
else Quickshell.execDetached(["killall", "mako", "dunst"])
}
if (openDialog) {
Quickshell.execDetached(["qs", "-p", root.killDialogQmlPath])
}
}
}
}
}

View file

@ -52,10 +52,11 @@ ShellRoot {
// Force initialization of some singletons
Component.onCompleted: {
Cliphist.refresh()
FirstRunExperience.load()
Hyprsunset.load()
MaterialThemeLoader.reapplyTheme()
Hyprsunset.load()
FirstRunExperience.load()
ConflictKiller.load()
Cliphist.refresh()
}
LazyLoader { active: enableBar && Config.ready && !Config.options.bar.vertical; component: Bar {} }