From fa6ef31538dfa3798bc92a24afa9b3950a7825dc Mon Sep 17 00:00:00 2001 From: Artem Bochkarev Date: Mon, 8 Jul 2019 14:25:32 +0300 Subject: [PATCH] touchbar: fixed IDEA-202927 Exception occurs on applying "Show F1, F2, etc. keys on the Touch Bar" option GitOrigin-RevId: 391644616ed688b571185fe51d5904acd4e0c9e1 --- .../ui/mac/touchbar/TouchBarSettingsTest.java | 15 +++++- .../ui/mac/foundation/NSDefaults.java | 50 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/platform/platform-tests/testSrc/com/intellij/ui/mac/touchbar/TouchBarSettingsTest.java b/platform/platform-tests/testSrc/com/intellij/ui/mac/touchbar/TouchBarSettingsTest.java index b8edbc3e8a4d..396854c3e70d 100644 --- a/platform/platform-tests/testSrc/com/intellij/ui/mac/touchbar/TouchBarSettingsTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ui/mac/touchbar/TouchBarSettingsTest.java @@ -11,6 +11,9 @@ import junit.framework.TestCase; import org.junit.Assume; import org.junit.Test; +import java.util.HashMap; +import java.util.Map; + public class TouchBarSettingsTest extends TestCase { private static final String testAppID = "com.apple.terminal"; @@ -47,7 +50,17 @@ public class TouchBarSettingsTest extends TestCase { public void testTouchBarSettingsWrite() { Assume.assumeTrue("NST-unsupported OS", NST.isSupportedOS()); - Assume.assumeTrue(NSDefaults.ourTouchBarDomain +" doesn't exist", NSDefaults.isDomainExists(NSDefaults.ourTouchBarDomain)); + if (NSDefaults.isDomainExists(NSDefaults.ourTouchBarDomain)) { + NSDefaults.removePersistentDomain(NSDefaults.ourTouchBarDomain); + Assume.assumeTrue("can't delete domain: " + NSDefaults.ourTouchBarDomain, !NSDefaults.isDomainExists(NSDefaults.ourTouchBarDomain)); + } + + final Map vals = new HashMap<>(); + vals.put("TestNSDefaultsKey", "TestNSDefaultsValue"); + vals.put("PresentationModePerApp", new HashMap<>()); + NSDefaults.createPersistentDomain(NSDefaults.ourTouchBarDomain, vals); + + Assume.assumeTrue("can't create domain: " + NSDefaults.ourTouchBarDomain, NSDefaults.isDomainExists(NSDefaults.ourTouchBarDomain)); final boolean enabled = NSDefaults.isShowFnKeysEnabled(testAppID); NSDefaults.setShowFnKeysEnabled(testAppID, !enabled); diff --git a/platform/util/ui/src/com/intellij/ui/mac/foundation/NSDefaults.java b/platform/util/ui/src/com/intellij/ui/mac/foundation/NSDefaults.java index 0a54a4f7d9ff..4b3c42b8bcab 100644 --- a/platform/util/ui/src/com/intellij/ui/mac/foundation/NSDefaults.java +++ b/platform/util/ui/src/com/intellij/ui/mac/foundation/NSDefaults.java @@ -4,9 +4,12 @@ package com.intellij.ui.mac.foundation; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.SystemInfo; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class NSDefaults { private static final Logger LOG = Logger.getInstance(NSDefaults.class); @@ -221,6 +224,16 @@ public class NSDefaults { public static boolean setShowFnKeysEnabled(String appId, boolean val) { return setShowFnKeysEnabled(appId, val, false); } public static boolean setShowFnKeysEnabled(String appId, boolean val, boolean performExtraDebugChecks) { + if (!isDomainExists(ourTouchBarDomain)) { + final Map vals = new HashMap<>(); + vals.put(ourTouchBarNode, new HashMap<>()); + createPersistentDomain(ourTouchBarDomain, vals); + if (!isDomainExists(ourTouchBarDomain)) { + LOG.error("can't create domain '" + ourTouchBarDomain + "'"); + return false; + } + } + final Path path = Path.createDomainPath(ourTouchBarDomain, ourTouchBarNode); String sval = path.readStringVal(appId); final boolean settingEnabled = sval != null && sval.equals(ourTouchBarShowFnValue); @@ -262,6 +275,43 @@ public class NSDefaults { return result.lastValidPos() >= 0; } + public static void createPersistentDomain(@NotNull String domainName, @Nullable Map values) { + final Foundation.NSAutoreleasePool pool = new Foundation.NSAutoreleasePool(); + try { + final ID defaults = Foundation.invoke("NSUserDefaults", "standardUserDefaults"); + if (defaults == null || defaults.equals(ID.NIL)) + return; + final ID dict = Foundation.invoke("NSMutableDictionary", "new"); + if (values != null) { + for (Map.Entry me: values.entrySet()) { + final Object val = me.getValue(); + if (val instanceof String) + Foundation.invoke(dict,"setObject:forKey:", Foundation.nsString((String)val), Foundation.nsString(me.getKey())); + else if (val instanceof Map) { + final ID internalDict = Foundation.invoke("NSMutableDictionary", "new"); + Foundation.invoke(dict,"setObject:forKey:", internalDict, Foundation.nsString(me.getKey())); + } else + LOG.error("unsupported type of domain value: " + String.valueOf(val)); + } + } + Foundation.invoke(defaults, "setPersistentDomain:forName:", dict, Foundation.nsString(domainName)); + } finally { + pool.drain(); + } + } + + public static void removePersistentDomain(@NotNull String domainName) { + final Foundation.NSAutoreleasePool pool = new Foundation.NSAutoreleasePool(); + try { + final ID defaults = Foundation.invoke("NSUserDefaults", "standardUserDefaults"); + if (defaults == null || defaults.equals(ID.NIL)) + return; + Foundation.invoke(defaults, "removePersistentDomainForName:", Foundation.nsString(domainName)); + } finally { + pool.drain(); + } + } + public static boolean isDarkMenuBar() { assert SystemInfo.isMac;