Commit 9e8dd321 authored by Artem Bochkarev's avatar Artem Bochkarev Committed by intellij-monorepo-bot
Browse files

IDEA-272894: release items of touchbar in AppKit

theoretically it can fix SIGSEGV at [libobjc.A.dylib] objc_msgSend in -[NSTouchBarViewController _updateTree]

(cherry picked from commit f545b89f023bf8a599f7785ab359cba83a520c53)
(cherry picked from commit 9270ec7186706febf5306caba2639d6ac7abacf6)

GitOrigin-RevId: a9cb18568d66b51a563bafe9e6d6395fe94087c5
parent ee1cae2f
Showing with 29 additions and 27 deletions
+29 -27
No preview for this file type
......@@ -84,7 +84,7 @@ void setPrincipal(id tbobj, const char * uid) {
}
__used
void releaseTouchBar(id tbobj) {
void releaseNativePeer(id tbobj) {
if ([NSThread isMainThread]) {
[tbobj release];
} else {
......
......@@ -78,7 +78,7 @@ final class NST {
ourNSTLibrary = null;
}
else {
ourNSTLibrary.releaseTouchBar(test);
ourNSTLibrary.releaseNativePeer(test);
LOG.info("nst library works properly, successfully created and released native touchbar object");
}
}
......@@ -111,8 +111,8 @@ final class NST {
return ourNSTLibrary.createTouchBar(name, creator, escID); // creates autorelease-pool internally
}
static void releaseTouchBar(ID tbObj) {
ourNSTLibrary.releaseTouchBar(tbObj);
static void releaseNativePeer(ID nativePeer) {
ourNSTLibrary.releaseNativePeer(nativePeer);
}
static void setTouchBar(@Nullable Window window, ID touchBarNativePeer) {
......@@ -257,10 +257,9 @@ final class NST {
@NotNull List<TBItemScrubber.ItemData> items = scrubber.getItems();
final Pair<Pointer, Integer> mem = _packItems(items.subList(fromIndex, fromIndex + itemsCount), itemsCount, withImages, withText);
synchronized (scrubber) {
final ID scrubObj = scrubber.getNativePeer();
if (scrubObj.equals(ID.NIL))
if (scrubber.myNativePeer.equals(ID.NIL))
return;
ourNSTLibrary.updateScrubberItems(scrubObj, mem == null ? null : mem.getFirst(), mem == null ? 0 : mem.getSecond(), fromIndex);
ourNSTLibrary.updateScrubberItems(scrubber.myNativePeer, mem == null ? null : mem.getFirst(), mem == null ? 0 : mem.getSecond(), fromIndex);
}
if (withImages && scrubber.getStats() != null)
scrubber.getStats().incrementCounter(StatsCounters.scrubberIconsProcessingDurationNs, System.nanoTime() - startNs);
......
......@@ -8,11 +8,12 @@ import com.sun.jna.Pointer;
interface NSTLibrary extends Library {
ID createTouchBar(String name, ItemCreator creator, String escId); // if defined escId => replace esc button with custom item
void releaseTouchBar(ID tbObj);
void setTouchBar(ID nsView, ID tbObj);
void selectItemsToShow(ID tbObj, String[] ids, int count);
void setPrincipal(ID tbObj, String uid);
void releaseNativePeer(ID nativePeerPtr);
interface Action extends Callback {
void execute();
}
......
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui.mac.touchbar;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
......@@ -10,7 +9,8 @@ import org.jetbrains.annotations.Nullable;
abstract class TBItem {
private final @NotNull String myName;
private @Nullable String myUid;
private @NotNull ID myNativePeer = ID.NIL; // java wrapper holds native object
@NotNull ID myNativePeer = ID.NIL; // java wrapper holds native object
final @Nullable ItemListener myListener;
boolean myIsVisible = true;
......@@ -36,14 +36,11 @@ abstract class TBItem {
return myNativePeer;
}
@NotNull
ID getNativePeer() { return myNativePeer; }
synchronized
void releaseNativePeer() {
if (myNativePeer == ID.NIL)
return;
Foundation.invoke(myNativePeer, "release");
NST.releaseNativePeer(myNativePeer);
myNativePeer = ID.NIL;
}
......
......@@ -127,9 +127,11 @@ class TBItemButton extends TBItem {
TBItemButton setHasArrowIcon(boolean hasArrowIcon) {
if (hasArrowIcon != myHasArrowIcon) {
myHasArrowIcon = hasArrowIcon;
if (getNativePeer() != ID.NIL) {
final Icon ic = myHasArrowIcon ? AllIcons.Mac.Touchbar.PopoverArrow : null;
NST.setArrowImage(getNativePeer(), ic);
synchronized (this) {
if (myNativePeer != ID.NIL) {
final Icon ic = myHasArrowIcon ? AllIcons.Mac.Touchbar.PopoverArrow : null;
NST.setArrowImage(myNativePeer, ic);
}
}
}
return this;
......@@ -245,7 +247,7 @@ class TBItemButton extends TBItem {
// Icons calculations can be slow, so we use async update
boolean updateLater(boolean force) {
if (!force && (!myIsVisible || myUpdateOptions == 0 || getNativePeer() == ID.NIL))
if (!force && (!myIsVisible || myUpdateOptions == 0 || myNativePeer == ID.NIL))
return false;
if (myRasterPromise != null && !myRasterPromise.isDone())
......@@ -267,10 +269,9 @@ class TBItemButton extends TBItem {
myUpdateOptions = 0;
synchronized (this) {
final ID nativePeer = getNativePeer();
if (nativePeer.equals(ID.NIL))
if (myNativePeer.equals(ID.NIL))
return;
NST.updateButton(nativePeer, updateOptions, layoutBits, validFlags, text, hint, isHintDisabled, raster, callback);
NST.updateButton(myNativePeer, updateOptions, layoutBits, validFlags, text, hint, isHintDisabled, raster, callback);
}
});
......
......@@ -75,11 +75,15 @@ class TBItemScrubber extends TBItem implements NSTLibrary.ScrubberDelegate {
id.myEnabled = enabled;
}
NST.enableScrubberItems(getNativePeer(), indices, enabled);
synchronized (this) {
NST.enableScrubberItems(myNativePeer, indices, enabled);
}
}
void showItems(Collection<Integer> indices, boolean visible, boolean inverseOthers) {
NST.showScrubberItem(getNativePeer(), indices, visible, inverseOthers);
synchronized (this) {
NST.showScrubberItem(myNativePeer, indices, visible, inverseOthers);
}
}
@Override
......
......@@ -130,7 +130,7 @@ class TouchBar implements NSTLibrary.ItemCreator {
synchronized(this) {
if (!myNativePeer.equals(ID.NIL)) {
NST.releaseTouchBar(myNativePeer);
NST.releaseNativePeer(myNativePeer);
myNativePeer = ID.NIL;
}
}
......
......@@ -31,7 +31,7 @@ public class NSTLibTest {
assertNotNull("Failed to create native touchbar object, result is null", test);
assertNotSame("Failed to create native touchbar object, result is ID.NIL", ID.NIL, test);
if (test != ID.NIL)
lib.releaseTouchBar(test);
lib.releaseNativePeer(test);
} catch (RuntimeException e) {
fail("nst library was loaded, but native object can't be created: " + e.getMessage());
}
......
......@@ -88,13 +88,13 @@ public class TouchbarTest {
txt = "show";
action = ()->SwingUtilities.invokeLater(()->{
ourVisible = !ourVisible;
NST.showScrubberItem(scrubber.getNativePeer(), _makeRandomCollection(size - 1), ourVisible, false);
NST.showScrubberItem(scrubber.myNativePeer, _makeRandomCollection(size - 1), ourVisible, false);
});
} else if (c == 2) {
txt = "enable";
action = ()->SwingUtilities.invokeLater(()->{
ourEnabled = !ourEnabled;
NST.enableScrubberItems(scrubber.getNativePeer(), _makeRandomCollection(size - 1), ourEnabled);
NST.enableScrubberItems(scrubber.myNativePeer, _makeRandomCollection(size - 1), ourEnabled);
});
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment