i18n-ja: add polling translation

This commit is contained in:
Ly-sec
2025-11-27 15:07:00 +01:00
16 changed files with 1436 additions and 177 deletions
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Dunkler Modus", "dark-mode": "Dunkler Modus",
"light-mode": "Heller Modus", "enabled": "Aktiviert",
"enabled": "Aktiviert" "light-mode": "Heller Modus"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "'Nicht stören' deaktiviert", "disabled": "'Nicht stören' deaktiviert",
+2 -2
View File
@@ -2082,8 +2082,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Dark Mode", "dark-mode": "Dark Mode",
"light-mode": "Light Mode", "enabled": "Enabled",
"enabled": "Enabled" "light-mode": "Light Mode"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "Do Not Disturb disabled", "disabled": "Do Not Disturb disabled",
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Modo oscuro", "dark-mode": "Modo oscuro",
"light-mode": "Modo claro", "enabled": "Activado",
"enabled": "Activado" "light-mode": "Modo claro"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "'No molestar' desactivado", "disabled": "'No molestar' desactivado",
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Mode sombre", "dark-mode": "Mode sombre",
"light-mode": "Mode clair", "enabled": "Activé",
"enabled": "Activé" "light-mode": "Mode clair"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "'Ne pas déranger' désactivé", "disabled": "'Ne pas déranger' désactivé",
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Donkere modus", "dark-mode": "Donkere modus",
"light-mode": "Lichte modus", "enabled": "Ingeschakeld",
"enabled": "Ingeschakeld" "light-mode": "Lichte modus"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "\"Niet storen\" uitgeschakeld", "disabled": "\"Niet storen\" uitgeschakeld",
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Modo escuro", "dark-mode": "Modo escuro",
"light-mode": "Modo claro", "enabled": "Ativado",
"enabled": "Ativado" "light-mode": "Modo claro"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "'Não perturbe' desativado", "disabled": "'Não perturbe' desativado",
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Тёмный режим", "dark-mode": "Тёмный режим",
"light-mode": "Светлый режим", "enabled": "Включен",
"enabled": "Включен" "light-mode": "Светлый режим"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "Режим 'Не беспокоить' отключен", "disabled": "Режим 'Не беспокоить' отключен",
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Karanlık mod", "dark-mode": "Karanlık mod",
"light-mode": "Aydınlık mod", "enabled": "Etkin",
"enabled": "Etkin" "light-mode": "Aydınlık mod"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "'Rahatsız etme' devre dışı", "disabled": "'Rahatsız etme' devre dışı",
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "Темний режим", "dark-mode": "Темний режим",
"light-mode": "Світлий режим", "enabled": "Увімкнено",
"enabled": "Увімкнено" "light-mode": "Світлий режим"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "'Не турбувати' вимкнено", "disabled": "'Не турбувати' вимкнено",
+2 -2
View File
@@ -2076,8 +2076,8 @@
}, },
"dark-mode": { "dark-mode": {
"dark-mode": "深色模式", "dark-mode": "深色模式",
"light-mode": "浅色模式", "enabled": "已启用",
"enabled": "已启用" "light-mode": "浅色模式"
}, },
"do-not-disturb": { "do-not-disturb": {
"disabled": "'勿扰模式'已禁用", "disabled": "'勿扰模式'已禁用",
@@ -14,6 +14,7 @@ RowLayout {
NBox { NBox {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: root.shortcutsHeight Layout.preferredHeight: root.shortcutsHeight
visible: Settings.data.controlCenter.shortcuts.left.length > 0
RowLayout { RowLayout {
id: leftContent id: leftContent
@@ -53,6 +54,7 @@ RowLayout {
NBox { NBox {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: root.shortcutsHeight Layout.preferredHeight: root.shortcutsHeight
visible: Settings.data.controlCenter.shortcuts.right.length > 0
RowLayout { RowLayout {
id: rightContent id: rightContent
@@ -249,7 +249,7 @@ ColumnLayout {
sectionName: I18n.tr("settings.control-center.shortcuts.sectionLeft") sectionName: I18n.tr("settings.control-center.shortcuts.sectionLeft")
sectionId: "left" sectionId: "left"
settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/ControlCenter/ControlCenterWidgetSettingsDialog.qml") settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/ControlCenter/ControlCenterWidgetSettingsDialog.qml")
maxWidgets: 5 maxWidgets: Settings.data.controlCenter.shortcuts["right"].length > 5 ? 0 : (Settings.data.controlCenter.shortcuts["right"].length > 0 ? 5 : 10)
widgetRegistry: ControlCenterWidgetRegistry widgetRegistry: ControlCenterWidgetRegistry
widgetModel: Settings.data.controlCenter.shortcuts["left"] widgetModel: Settings.data.controlCenter.shortcuts["left"]
availableWidgets: availableWidgets availableWidgets: availableWidgets
@@ -266,7 +266,7 @@ ColumnLayout {
sectionName: I18n.tr("settings.control-center.shortcuts.sectionRight") sectionName: I18n.tr("settings.control-center.shortcuts.sectionRight")
sectionId: "right" sectionId: "right"
settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/ControlCenter/ControlCenterWidgetSettingsDialog.qml") settingsDialogComponent: Qt.resolvedUrl(Quickshell.shellDir + "/Modules/Panels/Settings/ControlCenter/ControlCenterWidgetSettingsDialog.qml")
maxWidgets: 5 maxWidgets: Settings.data.controlCenter.shortcuts["left"].length > 5 ? 0 : (Settings.data.controlCenter.shortcuts["left"].length > 0 ? 5 : 10)
widgetRegistry: ControlCenterWidgetRegistry widgetRegistry: ControlCenterWidgetRegistry
widgetModel: Settings.data.controlCenter.shortcuts["right"] widgetModel: Settings.data.controlCenter.shortcuts["right"]
availableWidgets: availableWidgets availableWidgets: availableWidgets
+110 -112
View File
@@ -27,155 +27,153 @@ Item {
// Initialization // Initialization
function initialize() { function initialize() {
niriEventStream.running = true; niriEventStream.connected = true;
niriCommandSocket.connected = true;
startEventStream();
updateWorkspaces(); updateWorkspaces();
updateWindows(); updateWindows();
queryDisplayScales(); queryDisplayScales();
Logger.i("NiriService", "Service started"); Logger.i("NiriService", "Service started");
} }
// command from https://yalter.github.io/niri/niri_ipc/enum.Request.html
function sendSocketCommand(sock, command) {
sock.write(JSON.stringify(command) + "\n");
sock.flush();
}
function startEventStream() {
sendSocketCommand(niriEventStream, "EventStream");
}
// Update workspaces // Update workspaces
function updateWorkspaces() { function updateWorkspaces() {
niriWorkspaceProcess.running = true; sendSocketCommand(niriCommandSocket, "Workspaces");
} }
// Update windows // Update windows
function updateWindows() { function updateWindows() {
niriWindowsProcess.running = true; sendSocketCommand(niriCommandSocket, "Windows");
} }
// Query display scales // Query display scales
function queryDisplayScales() { function queryDisplayScales() {
niriOutputsProcess.running = true; sendSocketCommand(niriCommandSocket, "Outputs");
} }
// Niri outputs process for display scale detection function recollectOutputs(outputsData) {
Process { const scales = {};
id: niriOutputsProcess
running: false
command: ["niri", "msg", "--json", "outputs"]
stdout: SplitParser { // Niri returns an object with display names as keys
for (const outputName in outputsData) {
const output = outputsData[outputName];
if (output && output.name) {
const logical = output.logical || {};
const currentModeIdx = output.current_mode || 0;
const modes = output.modes || [];
const currentMode = modes[currentModeIdx] || {};
scales[output.name] = {
"name": output.name,
"scale": logical.scale || 1.0,
"width": logical.width || 0,
"height": logical.height || 0,
"x": logical.x || 0,
"y": logical.y || 0,
"physical_width": (output.physical_size && output.physical_size[0]) || 0,
"physical_height": (output.physical_size && output.physical_size[1]) || 0,
"refresh_rate": currentMode.refresh_rate || 0,
"vrr_supported": output.vrr_supported || false,
"vrr_enabled": output.vrr_enabled || false,
"transform": logical.transform || "Normal"
};
}
}
// Notify CompositorService (it will emit displayScalesChanged)
if (CompositorService && CompositorService.onDisplayScalesUpdated) {
CompositorService.onDisplayScalesUpdated(scales);
}
}
function recollectWorkspaces(workspacesData) {
const workspacesList = [];
for (const ws of workspacesData) {
workspacesList.push({
"id": ws.id,
"idx": ws.idx,
"name": ws.name || "",
"output": ws.output || "",
"isFocused": ws.is_focused === true,
"isActive": ws.is_active === true,
"isUrgent": ws.is_urgent === true,
"isOccupied": ws.active_window_id ? true : false
});
}
// Sort workspaces by output, then by index
workspacesList.sort((a, b) => {
if (a.output !== b.output) {
return a.output.localeCompare(b.output);
}
return a.idx - b.idx;
});
// Update the workspaces ListModel
workspaces.clear();
for (var i = 0; i < workspacesList.length; i++) {
workspaces.append(workspacesList[i]);
}
workspaceChanged();
}
// Niri command socket
Socket {
id: niriCommandSocket
path: Quickshell.env("NIRI_SOCKET")
connected: false
parser: SplitParser {
onRead: function (line) { onRead: function (line) {
try { try {
const outputsData = JSON.parse(line); const data = JSON.parse(line);
const scales = {};
// Niri returns an object with display names as keys if (data && data.Ok) {
for (const outputName in outputsData) { const res = data.Ok;
const output = outputsData[outputName]; if (res.Windows) {
if (output && output.name) { recollectWindows(res.Windows);
const logical = output.logical || {}; } else if (res.Outputs) {
const currentModeIdx = output.current_mode || 0; recollectOutputs(res.Outputs);
const modes = output.modes || []; } else if (res.Workspaces) {
const currentMode = modes[currentModeIdx] || {}; recollectWorkspaces(res.Workspaces);
scales[output.name] = {
"name": output.name,
"scale": logical.scale || 1.0,
"width": logical.width || 0,
"height": logical.height || 0,
"x": logical.x || 0,
"y": logical.y || 0,
"physical_width": (output.physical_size && output.physical_size[0]) || 0,
"physical_height": (output.physical_size && output.physical_size[1]) || 0,
"refresh_rate": currentMode.refresh_rate || 0,
"vrr_supported": output.vrr_supported || false,
"vrr_enabled": output.vrr_enabled || false,
"transform": logical.transform || "Normal"
};
} }
} } else {
Logger.e("NiriService", "Niri returned an error:", data.Err, line);
// Notify CompositorService (it will emit displayScalesChanged)
if (CompositorService && CompositorService.onDisplayScalesUpdated) {
CompositorService.onDisplayScalesUpdated(scales);
} }
} catch (e) { } catch (e) {
Logger.e("NiriService", "Failed to parse outputs:", e, line); Logger.e("NiriService", "Failed to parse data from socket:", e, line);
return;
} }
} }
} }
} }
// Niri workspace process // Niri event stream socket
Process { Socket {
id: niriWorkspaceProcess
running: false
command: ["niri", "msg", "--json", "workspaces"]
stdout: SplitParser {
onRead: function (line) {
try {
const workspacesData = JSON.parse(line);
const workspacesList = [];
for (const ws of workspacesData) {
workspacesList.push({
"id": ws.id,
"idx": ws.idx,
"name": ws.name || "",
"output": ws.output || "",
"isFocused": ws.is_focused === true,
"isActive": ws.is_active === true,
"isUrgent": ws.is_urgent === true,
"isOccupied": ws.active_window_id ? true : false
});
}
// Sort workspaces by output, then by index
workspacesList.sort((a, b) => {
if (a.output !== b.output) {
return a.output.localeCompare(b.output);
}
return a.idx - b.idx;
});
// Update the workspaces ListModel
workspaces.clear();
for (var i = 0; i < workspacesList.length; i++) {
workspaces.append(workspacesList[i]);
}
workspaceChanged();
} catch (e) {
Logger.e("NiriService", "Failed to parse workspaces:", e, line);
}
}
}
}
// Niri windows process
Process {
id: niriWindowsProcess
running: false
command: ["niri", "msg", "--json", "windows"]
stdout: SplitParser {
onRead: function (line) {
try {
const windowsData = JSON.parse(line);
recollectWindows(windowsData);
} catch (e) {
Logger.e("NiriService", "Failed to parse windows:", e, line);
}
}
}
}
// Niri event stream process
Process {
id: niriEventStream id: niriEventStream
running: false path: Quickshell.env("NIRI_SOCKET")
command: ["niri", "msg", "--json", "event-stream"] connected: false
stdout: SplitParser { parser: SplitParser {
onRead: data => { onRead: data => {
try { try {
const event = JSON.parse(data.trim()); const event = JSON.parse(data.trim());
if (event.WorkspacesChanged) { if (event.WorkspacesChanged) {
updateWorkspaces(); recollectWorkspaces(event.WorkspacesChanged.workspaces);
} else if (event.WindowOpenedOrChanged) { } else if (event.WindowOpenedOrChanged) {
handleWindowOpenedOrChanged(event.WindowOpenedOrChanged); handleWindowOpenedOrChanged(event.WindowOpenedOrChanged);
} else if (event.WindowClosed) { } else if (event.WindowClosed) {
+39 -39
View File
@@ -620,43 +620,6 @@ Popup {
columnSpacing: 6 columnSpacing: 6
rowSpacing: 6 rowSpacing: 6
Repeater {
model: ColorList.colors
Rectangle {
width: 24
height: 24
radius: Style.radiusXXS
color: modelData.color
border.color: root.selectedColor.toString() === modelData.color.toString() ? Color.mPrimary : Color.mOutline
border.width: Math.max(1, root.selectedColor.toString() === modelData.color.toString() ? Style.borderM : Style.borderS)
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: {
TooltipService.show(parent, modelData.name + "\n" + parent.color.toString().toUpperCase());
}
onExited: {
TooltipService.hide();
}
onClicked: {
root.selectedColor = modelData.color;
TooltipService.hide();
}
}
}
}
NDivider {
Layout.columnSpan: 15
Layout.fillWidth: true
Layout.topMargin: Style.marginXS
Layout.bottomMargin: 0
}
NLabel { NLabel {
Layout.columnSpan: 15 Layout.columnSpan: 15
Layout.fillWidth: true Layout.fillWidth: true
@@ -695,6 +658,43 @@ Popup {
} }
] ]
Rectangle {
width: 24
height: 24
radius: Style.radiusXXS
color: modelData.color
border.color: root.selectedColor.toString() === modelData.color.toString() ? Color.mPrimary : Color.mOutline
border.width: Math.max(1, root.selectedColor.toString() === modelData.color.toString() ? Style.borderM : Style.borderS)
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onEntered: {
TooltipService.show(parent, modelData.name + "\n" + parent.color.toString().toUpperCase());
}
onExited: {
TooltipService.hide();
}
onClicked: {
root.selectedColor = modelData.color;
TooltipService.hide();
}
}
}
}
NDivider {
Layout.columnSpan: 15
Layout.fillWidth: true
Layout.topMargin: Style.marginXS
Layout.bottomMargin: 0
}
Repeater {
model: ColorList.colors
Rectangle { Rectangle {
width: 24 width: 24
height: 24 height: 24
@@ -728,8 +728,8 @@ Popup {
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
//Layout.topMargin: 20 Layout.topMargin: 1
//Layout.bottomMargin: 20 Layout.bottomMargin: 1
spacing: 10 spacing: 10
Item { Item {
+3 -3
View File
@@ -19,7 +19,7 @@ NBox {
property string settingsDialogComponent: "BarWidgetSettingsDialog.qml" property string settingsDialogComponent: "BarWidgetSettingsDialog.qml"
readonly property real miniButtonSize: Style.baseWidgetSize * 0.65 readonly property real miniButtonSize: Style.baseWidgetSize * 0.65
readonly property bool isAtMaxCapacity: maxWidgets > 0 && widgetModel.length >= maxWidgets readonly property bool isAtMaxCapacity: maxWidgets >= 0 && widgetModel.length >= maxWidgets
signal addWidget(string widgetId, string section) signal addWidget(string widgetId, string section)
signal removeWidget(string section, int index) signal removeWidget(string section, int index)
@@ -93,8 +93,8 @@ NBox {
// Widget count indicator (when max is set) // Widget count indicator (when max is set)
NText { NText {
visible: root.maxWidgets > 0 visible: root.maxWidgets >= 0
text: "(" + widgetModel.length + "/" + root.maxWidgets + ")" text: root.maxWidgets === 0 ? "(LOCKED)" : "(" + widgetModel.length + "/" + root.maxWidgets + ")"
pointSize: Style.fontSizeS pointSize: Style.fontSizeS
color: root.isAtMaxCapacity ? Color.mError : Color.mOnSurfaceVariant color: root.isAtMaxCapacity ? Color.mError : Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter