From fcc4229ce9fa16b56472199f128c5b5c5683f03f Mon Sep 17 00:00:00 2001 From: Piotr Borkowski Date: Sat, 7 Feb 2026 17:58:10 +0100 Subject: [PATCH] refactor: v1.0.7 - implement full asynchronous non-blocking memory fetching --- ma-ram-monitor@lanote/README.md | 19 +- .../files/ma-ram-monitor@lanote/applet.js | 259 +++++++++++++----- .../files/ma-ram-monitor@lanote/metadata.json | 4 +- .../files/ma-ram-monitor@lanote/po/es.po | 14 +- .../files/ma-ram-monitor@lanote/po/fr.po | 27 +- .../po/ma-ram-monitor@lanote.pot | 18 +- .../files/ma-ram-monitor@lanote/po/pl.po | 14 +- .../ma-ram-monitor@lanote/stylesheet.css | 2 - ma-ram-monitor@lanote/info.json | 2 +- 9 files changed, 236 insertions(+), 123 deletions(-) diff --git a/ma-ram-monitor@lanote/README.md b/ma-ram-monitor@lanote/README.md index ae8efb67973..44a76b64ea1 100644 --- a/ma-ram-monitor@lanote/README.md +++ b/ma-ram-monitor@lanote/README.md @@ -2,15 +2,15 @@ A high-performance, customizable RAM monitor for the Cinnamon Desktop Environment. Designed with visual stability and system efficiency in mind. -![Moderately Advanced RAM Monitor Preview](screenshot.png) - ## Key Features -- **Kernel-Direct Data**: Reads memory statistics directly from `/proc/meminfo`. This ensures maximum accuracy and near-zero CPU overhead compared to spawning external processes like `free` or `top`. -- **Visual Stability Control**: Includes a "Monospace Mode" with customizable string padding. This prevents the panel from "jumping" or shifting when memory values change (e.g., switching from 9.9% to 10.0%). -- **Customizable Alerts**: Visual blinking warnings when RAM usage exceeds (or available memory falls below) user-defined thresholds. -- **Smart Interaction**: Left-click to launch your favorite system monitor (GNOME System Monitor, htop, btop, etc.). -- **Unit Flexibility**: Support for both Binary (GiB) and Decimal (GB) units. +* **Asynchronous Engine:** Built using GJS `Promises` and `async/await` patterns. It fetches data from `/proc/meminfo` in the background, ensuring your Cinnamon panel never stutters or freezes. +* **Visual Stability Control**: Includes a "Monospace Mode" with customizable string padding. This prevents the panel from "jumping" or shifting when memory values change (e.g., switching from 9.9% to 10.0%). +* **Customizable Alerts**: Visual blinking warnings when RAM usage exceeds (or available memory falls below) user-defined thresholds. +* **Smart Interaction**: Left-click to launch your favorite system monitor (GNOME System Monitor, htop, btop, etc.). +* **Unit Flexibility**: Support for both Binary (GiB) and Decimal (GB) units. +* **Clean Code:** Fully compliant with modern GJS standards, using `TextDecoder` for byte-to-string conversion to ensure a warning-free log (`.xsession-errors`). +* **Localization:** Full support for translations (gettext). ## Installation @@ -25,11 +25,6 @@ The applet utilizes the following Linux kernel metrics: - **MemTotal**: Total usable RAM. - **MemAvailable**: An estimate of how much memory is available for starting new applications, without swapping. -## Translations - -- English (Default) -- Polish (Full support) - ## License This project is distributed under the same license as the Cinnamon Desktop environment (GPLv2+). diff --git a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/applet.js b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/applet.js index b695fc7be50..14eef6f8bab 100644 --- a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/applet.js +++ b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/applet.js @@ -4,20 +4,25 @@ const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Settings = imports.ui.settings; const Gettext = imports.gettext; +const St = imports.gi.St; +const Clutter = imports.gi.Clutter; let _; /** * RAM Monitor Applet for Cinnamon - * * This applet provides real-time memory usage statistics. It is designed for - * visual stability by utilizing dynamic string padding and forced monospaced - * fonts to prevent panel "jumping" when values change. + * + * Features: + * - Asynchronous data fetching to prevent UI blocking. + * - Monospaced font stability for consistent panel layout. + * - Dynamic warning thresholds with visual blink alerts. */ -class MaRamMonitorApplet extends Applet.TextApplet { +class MaRamMonitorApplet extends Applet.Applet { constructor(metadata, orientation, panelHeight, instanceId) { super(orientation, panelHeight, instanceId); // Initialize settings and bind them to local properties + // This section sets up the applet's settings and binds them to properties on the applet instance. Each setting is linked to a method that updates the UI when the setting changes, ensuring that user preferences are reflected immediately without needing to restart the applet. this.settings = new Settings.AppletSettings(this, metadata.uuid, instanceId); // --- Core UI Settings --- @@ -34,54 +39,96 @@ class MaRamMonitorApplet extends Applet.TextApplet { this.settings.bindProperty(Settings.BindingDirection.IN, "warning-available", "warning_available", this._update_ui, null); // --- Layout Stability & Interaction --- - this.settings.bindProperty(Settings.BindingDirection.IN, "use-monospace", "use_monospace", this._update_ui, null); + this.settings.bindProperty(Settings.BindingDirection.IN, "use-monospace", "use_monospace", () => { + this._apply_label_style(); + this._update_ui(); + }, null); this.settings.bindProperty(Settings.BindingDirection.IN, "padding-size", "padding_size", this._update_ui, null); this.settings.bindProperty(Settings.BindingDirection.IN, "enable-click-launch", "enable_click_launch", null, null); this.settings.bindProperty(Settings.BindingDirection.IN, "custom-command", "custom_command", null, null); + // UI Container - Using BoxLayout for layout stability + // The applet's main container is a BoxLayout, which provides a stable and flexible layout for the label. This choice helps prevent layout shifts and ensures that the applet remains visually consistent regardless of the content being displayed. The main label is added to this box, and the box is then added to the applet's actor, forming the basic structure of the UI. + this._box = new St.BoxLayout(); + this._mainLabel = new St.Label({ + text: "", + y_align: Clutter.ActorAlign.CENTER + }); + + this.actor.add_child(this._box); + this._box.add_child(this._mainLabel); + // Internal State Management + // These properties manage the warning state and blinking effect. The _isWarningActive flag indicates whether the current memory usage is in a warning state based on user-defined thresholds. The _blinkState is used to toggle the visual state for the blinking effect. The _timeoutId and _blinkTimeoutId are used to manage the scheduling of the main update loop and the blink loop, allowing for proper cleanup when the applet is removed. + // The initialization of these properties ensures that the applet starts in a known state, with no active warnings and no scheduled loops until the main update loop is started. This contributes to the stability and predictability of the applet's behavior from the moment it is added to the panel. this._isWarningActive = false; this._blinkState = false; + this._timeoutId = 0; + this._blinkTimeoutId = 0; - // Kick off the independent loops - this._update_loop(); // Data processing - this._blink_loop(); // Visual animation + // Apply initial styles and start the update loops + // The initial call to _apply_label_style ensures that the font style is set according to user preferences right from the start, preventing any layout shifts when the applet first appears. The _update_loop and _blink_loop methods are then called to start the regular updates and warning animations, ensuring that the applet is fully functional as soon as it is added to the panel. + // The order of these calls is important: we apply styles before starting the loops to ensure that the UI is correctly styled before any updates occur, which contributes to a smoother user experience. + this._apply_label_style(); + this._update_loop(); + this._blink_loop(); } /** * Restarts the main update loop when user changes the frequency in settings. + * This ensures that the applet updates at the new interval without requiring a full restart, providing a seamless user experience when adjusting refresh rates. */ _on_frequency_changed() { - if (this._timeoutId) Mainloop.source_remove(this._timeoutId); + if (this._timeoutId) { + Mainloop.source_remove(this._timeoutId); + this._timeoutId = 0; + } this._update_loop(); } /** * Primary loop for fetching system memory data. - * Frequency is customizable via settings (e.g., every 1.0s). + * This loop is responsible for regularly updating the displayed memory information based on the user-defined frequency. It calls the asynchronous method to fetch memory data, processes it according to user settings, and updates the UI. The loop is designed to be efficient and responsive, ensuring that the applet remains up-to-date without causing performance issues. If the frequency setting is changed by the user, this loop will be restarted with the new interval to reflect the updated refresh rate. */ _update_loop() { this._update_ui(); let interval = parseFloat(this.frequency) * 1000; this._timeoutId = Mainloop.timeout_add(interval, () => { this._update_loop(); - return false; // Prevents automatic restart to allow manual interval control + return false; }); } /** * Secondary loop for the warning animation. - * Runs at a fixed 500ms interval for smooth blinking, regardless of data frequency. + * Includes existence checks and ensures the loop stops if the applet is removed. + * This loop toggles the "warning-blink" style class on the applet's actor to create a blinking effect when memory usage crosses user-defined thresholds. The loop runs every 500ms, but only applies the blinking effect when the warning state is active. If the applet is removed while this loop is running, it will detect that the main label no longer exists and will stop scheduling further iterations, preventing potential errors or crashes due to missing UI elements. */ _blink_loop() { + // Safety check: If the applet was removed, stop the loop immediately + if (!this._mainLabel) { + this._blinkTimeoutId = 0; + return false; // This stops the Mainloop + } + + // Warning state management - toggles the "warning-blink" style class based on thresholds if (this._isWarningActive) { this._blinkState = !this._blinkState; - if (this._blinkState) this.actor.add_style_class_name("warning-blink"); - else this.actor.remove_style_class_name("warning-blink"); + + if (this._blinkState) { + this.actor.add_style_class_name("warning-blink"); + } else { + this.actor.remove_style_class_name("warning-blink"); + } } else { - this.actor.remove_style_class_name("warning-blink"); - this._blinkState = false; + // Ensure visual state is reset when warning is no longer active + if (this._blinkState || this.actor.has_style_class_name("warning-blink")) { + this.actor.remove_style_class_name("warning-blink"); + this._blinkState = false; + } } + + // Schedule the next blink iteration this._blinkTimeoutId = Mainloop.timeout_add(500, () => { this._blink_loop(); return false; @@ -89,44 +136,63 @@ class MaRamMonitorApplet extends Applet.TextApplet { } /** - * Main UI renderer. - * Reads memory, formats strings with padding, and applies style overrides. + * Applies or removes monospace font styling based on user preference. + * This method is called both during initialization and when the user toggles the monospace setting. It ensures that the font style is updated immediately to reflect the user's choice, contributing to a stable and consistent layout in the panel. + * The use of monospace fonts can help prevent layout shifts by ensuring that all characters occupy the same width, which is particularly beneficial for displaying numerical data like memory usage. When monospace is enabled, the font is set to "monospace" with bold weight for better readability. When disabled, the font style is reset to the default, allowing for a more traditional appearance if the user prefers it. + * The method also includes a safety check to ensure that it only attempts to apply styles if the main label exists, preventing potential errors if the applet is removed while this method is being executed. + */ + _apply_label_style() { + if (!this._mainLabel) return; + if (this.use_monospace) { + this._mainLabel.set_style("font-family: monospace; font-weight: bold;"); + } else { + this._mainLabel.set_style(null); + } + } + + /** + * Main UI renderer - now asynchronous with safety checks. + * Includes robust error handling for file reading and parsing, and ensures that if the applet is removed while waiting for data, it will not attempt to update the UI, preventing potential errors or crashes. + * The method fetches memory information asynchronously to avoid blocking the main thread, processes the data according to user settings, and updates the display. It also manages the warning state based on user-defined thresholds and ensures that the UI remains responsive and accurate even in edge cases such as read errors or applet removal during asynchronous operations. */ - _update_ui() { - const memData = this._getMemInfo(); + async _update_ui() { + // Fetch memory data asynchronously + const memData = await this._getMemInfoAsync(); + + // GUARD: Check if the applet was removed while waiting for data + // If _mainLabel no longer exists, we stop execution to prevent errors + if (!this._mainLabel) return; + + // Handle case where memory data could not be retrieved if (!memData) { - this.set_applet_label(_("RAM error")); + this._mainLabel.set_text(_("RAM error")); return; } + // Data processing and display logic const { total, available } = memData; const used = total - available; const divisor = this.unit_type === "GiB" ? Math.pow(1024, 3) : Math.pow(1000, 3); - // Calculate numeric representations - const totalNum = (total * 1024 / divisor).toFixed(1); + // Calculate display values based on user settings + const totalNum = (total * 1024 / divisor); const mainNum = (this.show_mode === "used" ? (used * 1024) : (available * 1024)) / divisor; const pNum = (this.show_mode === "used" ? (used / total) : (available / total)) * 100; - /** - * PADDING LOGIC - * We use '\u00A0' (Non-Breaking Space) to prevent the UI engine from - * collapsing multiple spaces. When paired with a monospace font, - * this ensures the applet width remains constant. - */ - const NBSP = "\u00A0"; - let displayVal = mainNum.toFixed(1).toString(); - let displayTotal = totalNum.toString(); - let displayPercent = pNum.toFixed(1).toString(); - - // Apply padding ONLY when the user enables Monospace (stable width) mode + // Formatting with optional monospace padding + const NBSP = "\u00A0"; // Non-breaking space + let displayVal = mainNum.toFixed(1); + let displayTotal = totalNum.toFixed(1); + let displayPercent = pNum.toFixed(1); + + // Apply padding for monospace if enabled if (this.use_monospace) { displayVal = displayVal.padStart(this.padding_size, NBSP); displayTotal = displayTotal.padStart(this.padding_size, NBSP); displayPercent = displayPercent.padStart(this.padding_size, NBSP); } - // Build the content string based on user visibility toggles + // Construct the display string based on user preferences let content = ""; if (this.show_value) { content += displayVal; @@ -134,41 +200,27 @@ class MaRamMonitorApplet extends Applet.TextApplet { content += " " + this.unit_type; } + // Add percentage display if enabled if (this.show_percent) { let spacePrefix = this.show_value ? " " : ""; content += spacePrefix + "(" + displayPercent + "%)"; } - // Default fallback if all display options are disabled + // If neither value nor percent is shown, default to showing percent for clarity if (!this.show_value && !this.show_percent) { content = displayPercent + "%"; } - /** - * FINAL STRING ASSEMBLY - * We concatenate the prefix label and content directly. - * If the user wants a space, they can include it in the 'mem-label' setting. - */ - let prefixLabel = this.mem_label ? this.mem_label : ""; - this.set_applet_label(prefixLabel + content); - - /** - * STYLING ENFORCEMENT - * We target the underlying St.Label actor directly to override - * theme-specific font settings when Monospace mode is active. - */ - let labelActor = this.actor.get_first_child(); - if (labelActor) { - if (this.use_monospace) { - labelActor.set_style("font-family: monospace; font-weight: bold;"); - } else { - labelActor.set_style(""); - } - } + // Add optional prefix label from settings + let prefixText = this.mem_label ? this.mem_label : ""; + + // Update the main label with the constructed content + this._mainLabel.set_text(prefixText + content); + // Update tooltip to reflect current display mode this.set_applet_tooltip(this.show_mode === "used" ? _("Used RAM") : _("Available RAM")); - // Determine if usage/availability cross the user-defined warning thresholds + // Warning Logic - Determine if warning state should be active based on thresholds if (this.show_mode === "used") { this._isWarningActive = this.warning_usage < 100 && parseFloat(pNum) >= this.warning_usage; } else { @@ -177,23 +229,56 @@ class MaRamMonitorApplet extends Applet.TextApplet { } /** - * Reads /proc/meminfo to get raw memory statistics. - * Values are provided in kB by the kernel. + * Reads /proc/meminfo asynchronously to prevent GUI stutters. + * Optimized to stop parsing as soon as required fields are found. */ - _getMemInfo() { + async _getMemInfoAsync() { try { let file = Gio.File.new_for_path("/proc/meminfo"); - let [, contents] = file.load_contents(null); - let text = contents.toString(); - let totalMatch = text.match(/MemTotal:\s+(\d+)/); - let availMatch = text.match(/MemAvailable:\s+(\d+)/); - if (totalMatch && availMatch) { - return { total: parseInt(totalMatch[1]), available: parseInt(availMatch[1]) }; + + // Read file contents asynchronously + // The use of a Promise here allows us to read the file without blocking the main thread. The load_contents_async method is called, and we wait for it to complete using the Promise. If the file is read successfully, we resolve the Promise with the contents; if there is an error, we reject it with an appropriate error message. + // The contents are returned as a byte array, which we will decode into a string for processing. + const contents = await new Promise((resolve, reject) => { + file.load_contents_async(null, (obj, res) => { + try { + let [success, contents] = obj.load_contents_finish(res); + if (success) resolve(contents); + else reject(new Error("Could not read file")); + } catch (e) { + reject(e); + } + }); + }); + + // FIX: Use TextDecoder instead of contents.toString() + // This prevents the Gjs-WARNING and ensures future compatibility. + let decoder = new TextDecoder('utf-8'); + let text = decoder.decode(contents); + let lines = text.split('\n'); + + let memInfo = { total: null, available: null }; + + // Parse lines to find MemTotal and MemAvailable + // The loop iterates through each line of the /proc/meminfo output, looking for the lines that start with "MemTotal:" and "MemAvailable:". When it finds these lines, it extracts the numerical value by removing all non-digit characters and parsing the result as an integer. The loop is optimized to stop as soon as both values are found, which can improve performance on systems with large memory where the relevant information is near the top of the file. + for (let line of lines) { + if (line.startsWith('MemTotal:') && memInfo.total === null) { + memInfo.total = parseInt(line.replace(/\D/g, '')); + } else if (line.startsWith('MemAvailable:') && memInfo.available === null) { + memInfo.available = parseInt(line.replace(/\D/g, '')); + } + + // Optimization: Stop parsing once we have both values + if (memInfo.total !== null && memInfo.available !== null) break; } + + // Return only if we have both values and they are valid numbers + return (memInfo.total > 0 && memInfo.available > 0) ? memInfo : null; + } catch (e) { global.logError(`[MaRamMonitorApplet]: ` + _("Kernel read error: %s").replace("%s", e.message)); + return null; } - return null; } /** @@ -212,19 +297,49 @@ class MaRamMonitorApplet extends Applet.TextApplet { } /** - * Cleanup resources when the applet is removed. + * Cleanup resources when the applet is removed from the panel. + * Ensures all loops are terminated and references are cleared. + * This prevents potential memory leaks and ensures that the applet can be safely removed without leaving behind orphaned processes or UI elements. + * The existence checks in the loops ensure that if the applet is removed while an asynchronous operation is pending, the loops will stop gracefully without throwing errors due to missing UI elements. + * This method is crucial for maintaining the stability and performance of the Cinnamon desktop environment, especially when users frequently add and remove applets from their panels. */ on_applet_removed_from_panel() { - if (this._timeoutId) Mainloop.source_remove(this._timeoutId); - if (this._blinkTimeoutId) Mainloop.source_remove(this._blinkTimeoutId); + if (this._timeoutId) { + Mainloop.source_remove(this._timeoutId); + this._timeoutId = 0; + } + + if (this._blinkTimeoutId) { + Mainloop.source_remove(this._blinkTimeoutId); + this._blinkTimeoutId = 0; + } + + this._mainLabel = null; + this._box = null; } } +/** + * Initializes gettext translations for the applet. + * Ensures that all user-facing strings can be localized based on the applet's UUID and locale directory. + * This function is called once during the applet's main initialization. + * @param {*} uuid The unique identifier for the applet, used to locate translation files. + */ function initTranslations(uuid) { Gettext.bindtextdomain(uuid, GLib.get_home_dir() + "/.local/share/cinnamon/applets/" + uuid + "/locale"); _ = (str) => Gettext.dgettext(uuid, str); } +/** + * Main entry point for the applet. Called by Cinnamon when the applet is added to the panel. + * Initializes translations and creates an instance of the MaRamMonitorApplet class. + * The parameters are provided by Cinnamon and include metadata about the applet, its orientation, panel height, and instance ID. + * @param {*} metadata An object containing metadata about the applet, such as its UUID, name, description, version, etc. This is defined in the applet's metadata.json file. + * @param {*} orientation The orientation of the panel where the applet is placed (e.g., St.Side.TOP, St.Side.BOTTOM, etc.). This can be used to adjust the applet's layout or styling based on its position. + * @param {*} panelHeight The height of the panel in pixels. This can be useful for scaling the applet's UI elements appropriately to fit within the panel. + * @param {*} instanceId A unique identifier for this instance of the applet. This is important for managing multiple instances of the same applet and ensuring that settings are applied correctly to each instance. + * @returns {MaRamMonitorApplet} An instance of the MaRamMonitorApplet class, which will be managed by Cinnamon. + */ function main(metadata, orientation, panelHeight, instanceId) { initTranslations(metadata.uuid); return new MaRamMonitorApplet(metadata, orientation, panelHeight, instanceId); diff --git a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/metadata.json b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/metadata.json index 7303fe77d17..ee5e225b81a 100644 --- a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/metadata.json +++ b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/metadata.json @@ -2,7 +2,7 @@ "uuid": "ma-ram-monitor@lanote", "name": "Moderately Advanced RAM Monitor", "description": "A customizable RAM monitor. Reads memory statistics directly from the kernel's virtual filesystem (/proc/meminfo) for maximum accuracy and low overhead.", - "version": "1.0.0", + "version": "1.0.7", "max-instances": -1, - "author": "Rezyder" + "author": "notoyeah" } diff --git a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/es.po b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/es.po index 91c2bf8fa33..f783d18e995 100644 --- a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/es.po +++ b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/es.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: ma-ram-monitor@lanote 1.0.0\n" "Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-applets/" "issues\n" -"POT-Creation-Date: 2026-02-01 17:50+0100\n" +"POT-Creation-Date: 2026-02-07 17:42+0100\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -18,30 +18,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 3.8\n" -#. applet.js:98 +#. applet.js:168 msgid "RAM error" msgstr "Error de RAM" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Used RAM" msgstr "RAM usada" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Available RAM" msgstr "RAM disponible" -#. applet.js:194 +#. applet.js:279 #, javascript-format msgid "Kernel read error: %s" msgstr "Error de lectura del núcleo: %s" -#. applet.js:209 +#. applet.js:294 msgid "RAM Applet error" msgstr "Error del applet RAM" -#. applet.js:209 +#. applet.js:294 #, javascript-format msgid "Command \"%s\" not found." msgstr "Comando \"%s\" no encontrado." diff --git a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/fr.po b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/fr.po index efcc51f6fc3..c869e47ceef 100644 --- a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/fr.po +++ b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/fr.po @@ -5,8 +5,9 @@ msgid "" msgstr "" "Project-Id-Version: ma-ram-monitor@lanote 1.0.0\n" -"Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-applets/issues\n" -"POT-Creation-Date: 2026-02-01 17:50+0100\n" +"Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-applets/" +"issues\n" +"POT-Creation-Date: 2026-02-07 17:42+0100\n" "PO-Revision-Date: 2026-02-04 10:07+0100\n" "Last-Translator: FabRCT\n" "Language-Team: none\n" @@ -16,30 +17,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#. applet.js:98 +#. applet.js:168 msgid "RAM error" msgstr "Erreur de RAM" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Used RAM" msgstr "RAM utilisée" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Available RAM" msgstr "RAM disponible" -#. applet.js:194 +#. applet.js:279 #, javascript-format msgid "Kernel read error: %s" msgstr "Erreur de lecture du noyau : %s" -#. applet.js:209 +#. applet.js:294 msgid "RAM Applet error" msgstr "Erreur de l'applet RAM" -#. applet.js:209 +#. applet.js:294 #, javascript-format msgid "Command \"%s\" not found." msgstr "Commande \"%s\" introuvable." @@ -136,7 +137,9 @@ msgstr "Afficher la mémoire totale" #. settings-schema.json->show-total->tooltip msgid "Toggle whether to display total RAM capacity next to the current usage." -msgstr "Afficher ou non de la capacité totale de la RAM à côté de son utilisation actuelle." +msgstr "" +"Afficher ou non de la capacité totale de la RAM à côté de son utilisation " +"actuelle." #. settings-schema.json->show-percent->description msgid "Show current memory as percentage" @@ -168,7 +171,8 @@ msgstr "Largeur stable (police à chasse fixe)" #. settings-schema.json->use-monospace->tooltip msgid "Forces a fixed-width font and prevents text jumping." -msgstr "Force l'utilisation d'une police à chasse fixe et empêche le saut de texte." +msgstr "" +"Force l'utilisation d'une police à chasse fixe et empêche le saut de texte." #. settings-schema.json->padding-size->units msgid "chars" @@ -180,7 +184,8 @@ msgstr "Espaces réservés pour les nombres" #. settings-schema.json->padding-size->tooltip msgid "How many characters to reserve for numbers (e.g. 4 for '99.9')." -msgstr "Combien de caractères sont réservés aux nombres (par exemple, 4 pour '99,9')." +msgstr "" +"Combien de caractères sont réservés aux nombres (par exemple, 4 pour '99,9')." #. settings-schema.json->layout_alerts->description msgid "Warnings" diff --git a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/ma-ram-monitor@lanote.pot b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/ma-ram-monitor@lanote.pot index 9fd93bfd227..5b9c51672a7 100644 --- a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/ma-ram-monitor@lanote.pot +++ b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/ma-ram-monitor@lanote.pot @@ -1,14 +1,14 @@ # MODERATELY ADVANCED RAM MONITOR # This file is put in the public domain. -# notoyeah, 2016 +# notoyeah, 2026 # #, fuzzy msgid "" msgstr "" -"Project-Id-Version: ma-ram-monitor@lanote 1.0.0\n" +"Project-Id-Version: ma-ram-monitor@lanote 1.0.7\n" "Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-applets/" "issues\n" -"POT-Creation-Date: 2026-02-01 17:50+0100\n" +"POT-Creation-Date: 2026-02-07 17:42+0100\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -17,30 +17,30 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#. applet.js:98 +#. applet.js:168 msgid "RAM error" msgstr "" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Used RAM" msgstr "" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Available RAM" msgstr "" -#. applet.js:194 +#. applet.js:279 #, javascript-format msgid "Kernel read error: %s" msgstr "" -#. applet.js:209 +#. applet.js:294 msgid "RAM Applet error" msgstr "" -#. applet.js:209 +#. applet.js:294 #, javascript-format msgid "Command \"%s\" not found." msgstr "" diff --git a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/pl.po b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/pl.po index 9d2b2212ff8..7138ee69e8e 100644 --- a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/pl.po +++ b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/po/pl.po @@ -9,7 +9,7 @@ msgstr "" "Project-Id-Version: ma-ram-monitor@lanote 1.0.0\n" "Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-applets/" "issues\n" -"POT-Creation-Date: 2026-02-01 17:50+0100\n" +"POT-Creation-Date: 2026-02-07 17:42+0100\n" "PO-Revision-Date: 2026-02-01 17:50+0100\n" "Last-Translator: Piotr Borkowski \n" "Language-Team: Polish\n" @@ -21,30 +21,30 @@ msgstr "" "|| n%100>=20) ? 1 : 2);\n" "X-Generator: Poedit 3.4.2\n" -#. applet.js:98 +#. applet.js:168 msgid "RAM error" msgstr "Błąd RAM" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Used RAM" msgstr "Wykorzystana pamięć RAM" #. settings-schema.json->show-mode->options -#. applet.js:169 +#. applet.js:221 msgid "Available RAM" msgstr "Dostępna pamięć RAM" -#. applet.js:194 +#. applet.js:279 #, javascript-format msgid "Kernel read error: %s" msgstr "Błąd odczytu jądra: %s" -#. applet.js:209 +#. applet.js:294 msgid "RAM Applet error" msgstr "Błąd RAM Applet" -#. applet.js:209 +#. applet.js:294 #, javascript-format msgid "Command \"%s\" not found." msgstr "Polecenie \"%s\" nie zostało znalezione." diff --git a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/stylesheet.css b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/stylesheet.css index a055839f6c2..7e201be39b3 100644 --- a/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/stylesheet.css +++ b/ma-ram-monitor@lanote/files/ma-ram-monitor@lanote/stylesheet.css @@ -1,5 +1,3 @@ .warning-blink { background-color: rgba(255, 0, 0, 0.5); - border-radius: 2px; - transition: background-color 0.2s ease-in-out; } diff --git a/ma-ram-monitor@lanote/info.json b/ma-ram-monitor@lanote/info.json index b38f8f1346d..49b1f42c012 100644 --- a/ma-ram-monitor@lanote/info.json +++ b/ma-ram-monitor@lanote/info.json @@ -2,6 +2,6 @@ "uuid": "ma-ram-monitor@lanote", "name": "Moderately Advanced RAM Monitor", "description": "A customizable RAM monitor. Reads memory statistics directly from the kernel's virtual filesystem (/proc/meminfo) for maximum accuracy and low overhead.", - "version": "1.0.0", + "version": "1.0.7", "author": "notoyeah" }