Repository: MegaMek/megameklab
Pull request #1891: fix: checks if OS is mac and dont load the html for the recent files in the menu bar
Author: login: Scoppio
Labels: name: GUI
description: User-interface related issue
name: Mac
description: Issues that related to ONLY a Mac
Created: 2025-05-18T02:34:15Z | Merged: 2025-05-18T21:39:00Z

# What it does?

On MegaMekLab the "Recent files" in the menu bar appear with a bunch of html tags written in raw text. Apparently when adapting the look and feel of the OS it also gains some of its quirks, mac in particular is not able or not willing to render HTML on the menu bar in the way we setup it right now.

This PR checks if the OS is mac or not, and if it is mac it won't load the html tags 

Before:
![image](https://github.com/user-attachments/assets/90837223-4476-4d26-964d-398af4d942ff)

After:
<img width="702" alt="Screenshot 2025-05-17 at 23 32 40" src="https://github.com/user-attachments/assets/ff270d1b-cb95-42c3-8e15-80966fef4c0d" />




Diff:
diff --git a/megameklab/src/megameklab/ui/MenuBar.java b/megameklab/src/megameklab/ui/MenuBar.java
index 6fc5b7a7def..09faea56313 100644
--- a/megameklab/src/megameklab/ui/MenuBar.java
+++ b/megameklab/src/megameklab/ui/MenuBar.java
@@ -49,6 +49,7 @@
 import megameklab.ui.dialog.PrintQueueDialog;
 import megameklab.ui.dialog.UiLoader;
 import megameklab.ui.dialog.settings.SettingsDialog;
+import megameklab.ui.util.OSUtil;
 import megameklab.util.CConfig;
 import megameklab.util.UnitPrintManager;
 import megameklab.util.UnitUtil;
@@ -760,10 +761,18 @@ private JMenu createThemesMenu() {
                 path = path.substring(0, 40) + "...";
             }
         }
-        String html = "<HTML><HEAD><STYLE>%s</STYLE></HEAD><BODY>%s</BODY></HTML>";
-        String style = ".small { font-size:smaller; color:gray; }";
-        String content = "<NOBR>%d. %s<BR>".formatted(fileNumber, recent.getName()) + UIUtil.spanCSS("small", path);
-        final JMenuItem miCConfig = new JMenuItem(html.formatted(style, content));
+
+        String content;
+        if (OSUtil.isMac()) {
+             content = "%d. %s ".formatted(fileNumber, recent.getName()) + "(" + path + ")";
+        } else {
+            String html = "<HTML><HEAD><STYLE>%s</STYLE></HEAD><BODY>%s</BODY></HTML>";
+            String style = ".small { font-size:smaller; color:gray; }";
+            content = html.formatted(style, "<NOBR>%d. %s<BR>".formatted(fileNumber,
+                  recent.getName()) + UIUtil.spanCSS("small", path));
+        }
+
+        final JMenuItem miCConfig = new JMenuItem(content);
         miCConfig.setName("miCConfig");
         miCConfig.addActionListener(evt -> loadUnitFromFile(fileNumber));
         miCConfig.setMnemonic(48 + fileNumber); // the number itself, i.e. 1, 2, 3 etc.
diff --git a/megameklab/src/megameklab/ui/util/OSUtil.java b/megameklab/src/megameklab/ui/util/OSUtil.java
new file mode 100644
index 00000000000..8e2af9ddb09
--- /dev/null
+++ b/megameklab/src/megameklab/ui/util/OSUtil.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2025 The MegaMek Team. All Rights Reserved.
+ *
+ * This file is part of MegaMek.
+ *
+ * MegaMek is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (GPL),
+ * version 3 or (at your option) any later version,
+ * as published by the Free Software Foundation.
+ *
+ * MegaMek is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * A copy of the GPL should have been included with this project;
+ * if not, see <https://www.gnu.org/licenses/>.
+ *
+ * NOTICE: The MegaMek organization is a non-profit group of volunteers
+ * creating free software for the BattleTech community.
+ *
+ * MechWarrior, BattleMech, `Mech and AeroTech are registered trademarks
+ * of The Topps Company, Inc. All Rights Reserved.
+ *
+ * Catalyst Game Labs and the Catalyst Game Labs logo are trademarks of
+ * InMediaRes Productions, LLC.
+ *
+ * MechWarrior Copyright Microsoft Corporation. MegaMek was created under
+ * Microsoft's "Game Content Usage Rules"
+ * <https://www.xbox.com/en-US/developers/rules> and it is not endorsed by or
+ * affiliated with Microsoft.
+ */
+package megameklab.ui.util;
+
+/**
+ * Utility class to determine the operating system.
+ * @author Luana Coppio
+ */
+public class OSUtil {
+    public enum OS {
+        WINDOWS,
+        MAC,
+        LINUX,
+        OTHER
+    }
+
+    private static OS os = null;
+
+    /**
+     * Returns the current operating system.
+     * @return {@link OS}
+     */
+    public static OS getOS() {
+        if (os == null) {
+            String osName = System.getProperty("os.name").toLowerCase();
+            if (osName.contains("win")) {
+                os = OS.WINDOWS;
+            } else if (osName.contains("mac") || osName.contains("darwin")) {
+                os = OS.MAC;
+            } else if (osName.contains("nix") || osName.contains("nux")) {
+                os = OS.LINUX;
+            } else {
+                os = OS.OTHER;
+            }
+        }
+        return os;
+    }
+
+    /**
+     * @return true if the current operating system is Mac
+     */
+    public static boolean isMac() {
+        return OS.MAC.equals(getOS());
+    }
+
+    /**
+     * @return true if the current operating system is Windows
+     */
+    public static boolean isWindows() {
+        return OS.WINDOWS.equals(getOS());
+    }
+
+    /**
+     * @return true if the current operating system is Linux
+     */
+    public static boolean isLinux() {
+        return OS.LINUX.equals(getOS());
+    }
+
+}


Reviews:
user: login: exeea
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-18T21:36:09Z
user: login: Sleet01
body: LGTM
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-18T21:36:41Z
user: login: exeea
body: Approved!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-18T21:36:43Z
user: login: Scoppio
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-18T21:38:45Z

Review comments:
path: megameklab/src/megameklab/ui/util/OSUtil.java
user: login: exeea
body: Similar OS checks are used in:
PrintRecordSheet.java
SingleinstanceService.java
MekHQ.java

I think this helper is worth of megamek.common and then be used in all 4 places.
created_at: 2025-05-18T21:36:09Z
author_association: COLLABORATOR
path: megameklab/src/megameklab/ui/util/OSUtil.java
user: login: Scoppio
body: Agreed, after this release we do this move
created_at: 2025-05-18T21:38:45Z
author_association: COLLABORATOR

PR comments:
user: login: exeea
created_at: 2025-05-18T11:22:38Z
body: What about render it styled but without using HTML to keep the same look between OSes?
author_association: COLLABORATOR
user: login: Scoppio
created_at: 2025-05-18T21:33:56Z
body: > What about render it styled but without using HTML to keep the same look between OSes?

Just for reference to whoever see this PR later: - We tried this solution and it did not work. MacOS is annoying like that.
author_association: COLLABORATOR
user: login: codecov[bot]
created_at: 2025-05-18T21:39:06Z
body: ## [Codecov](https://app.codecov.io/gh/MegaMek/megameklab/pull/1891?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 0.00%. Comparing base [(`e0c8bfc`)](https://app.codecov.io/gh/MegaMek/megameklab/commit/e0c8bfca946f10c6653c7b08f6e9fd9afb84e2da?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek) to head [(`4069540`)](https://app.codecov.io/gh/MegaMek/megameklab/commit/406954033c1431cc69692f2931ddee32f6cd1d7e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek).
> Report is 3 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@      Coverage Diff       @@
##   master   #1891   +/-   ##
==============================
==============================

```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/MegaMek/megameklab/pull/1891?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MegaMek).

<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
</details>
author_association: NONE