Firefox Extension/Addon - Detect workspace locked - firefox
I'm searching for a solution in my firefox addon to detect when the user workspace has locked/released. In google chrome there is an easy API chrome.idle.onStateChanged.addListener for it, is there something similar in firefox or any possibility to do that, platform independent?
By the way, I use the addon sdk.
I've already tried the idle service:
Cc["#mozilla.org/widget/idleservice;1"].getService(Ci.nsIIdleService)
but I just gives me access to some idle timeout or system when go to sleep and not to just workspace locked.
Edit: With "workspace locked" I mean the user lock the workspace with ctrl + alt + delete. I don't know how this exactly work on OSX or linux.
Edit2: I working in Windows 8.1 currently, but I guess the chrome.idle handler works cross platform.
Edit3: What i currently get out of current answers is
1. That there not exist a cross-platform solution, neither in chrome nor in firefox.
chrome.idle.onStateChanged seems to work different on windows, linux and osx. Only windows can handle that "locked" behaviour as expected. I can't test OSX, on ubuntu 14 it doesn't work for me.
2. For firefox there some in-depth code things to try to make it working - see answer bellow from Noitidart in this topic.
Edit4: Noitidart have found a solution for windows - github link.
I don't know how to detect screen lock but there are these observer notifications:
https://developer.mozilla.org/en-US/docs/Observer_Notifications#Idle_Service
Also the computer sleep wake notifications. ill ask around for lock screen thats an interesting one.
Some useful chat about the subject, looking at how google chrome does it:
[12:33] ok guys question about actual work. anyone know how to detect if screen was locked? apparently google chrome has a method: https://developer.chrome.com/extensions/idle#event-onStateChanged
[12:45] anyone know of a MXR or DXR for google chromes codebase?
[12:46] mxr.mozilla.org/chromium
[12:52] Ms2ger: can you help me find how they test screen lock. im looking here: http://mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_api_unittest.cc#84
[12:56] oh yuck it looks like they poll: http://mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_manager.h#118
maybe they arent polling.
check this out:
http://mxr.mozilla.org/chromium/source/src/chrome/browser/extensions/api/idle/idle_manager.cc#246
244 void IdleManager::UpdateIdleStateCallback(int idle_time) {
245 DCHECK(thread_checker_.CalledOnValidThread());
246 bool locked = idle_time_provider_->CheckIdleStateIsLocked();
247 int listener_count = 0;
leads to: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_win.cc#52
52 bool CheckIdleStateIsLocked() {
53 return ui::IsWorkstationLocked() || IsScreensaverRunning();
54 }
so this leads us to test if screensaver running or workstation locked
leads to:
http://mxr.mozilla.org/chromium/search?string=IsWorkstationLocked
we see just one implementation (its curious because there is no linux support but it doesnt say so on the chrome docs page, so maybe i couldnt find it)
Windows
http://mxr.mozilla.org/chromium/source/src/ui/base/win/lock_state.cc#11
11 bool IsWorkstationLocked() {
12 bool is_locked = true;
13 HDESK input_desk = ::OpenInputDesktop(0, 0, GENERIC_READ);
14 if (input_desk) {
15 wchar_t name[256] = {0};
16 DWORD needed = 0;
17 if (::GetUserObjectInformation(
18 input_desk, UOI_NAME, name, sizeof(name), &needed)) {
19 is_locked = lstrcmpi(name, L"default") != 0;
20 }
21 ::CloseDesktop(input_desk);
22 }
23 return is_locked;
24 }
Mac
see the screensaver section below, the screenlock is handled via there as well
http://mxr.mozilla.org/chromium/search?string=IsScreensaverRunning&find=&findi=&filter=^%5B^\0%5D*%24&hitlimit=&tree=chromium
we see in this search results 2 implementations, mac and windows it looks like no support for linux, which is curious because the chrome.idle page doesnt mention this on docs, maybe i just couldnt find it
windows implementation: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_win.cc#39
39 bool IsScreensaverRunning() {
40 DWORD result = 0;
41 if (::SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &result, 0))
42 return result != FALSE;
43 return false;
44 }
45
mac implementation: http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_mac.mm#28
28 - (id)init {
29 if ((self = [super init])) {
30 NSDistributedNotificationCenter* distCenter =
31 [NSDistributedNotificationCenter defaultCenter];
32 [distCenter addObserver:self
33 selector:#selector(onScreenSaverStarted:)
34 name:#"com.apple.screensaver.didstart"
35 object:nil];
36 [distCenter addObserver:self
37 selector:#selector(onScreenSaverStopped:)
38 name:#"com.apple.screensaver.didstop"
39 object:nil];
40 [distCenter addObserver:self
41 selector:#selector(onScreenLocked:)
42 name:#"com.apple.screenIsLocked"
43 object:nil];
44 [distCenter addObserver:self
45 selector:#selector(onScreenUnlocked:)
46 name:#"com.apple.screenIsUnlocked"
47 object:nil];
48 }
49 return self;
50 }
so to sum this all up:
[13:32] for windows its peice of cake winapi has call to test if screen is locked or scrensaver running
[13:32] for mac they dont have screen lock test. they just have screensaver test, but its an observer method
[13:32] for linux they dont have screen lock nor screen saver test. real odd. ill ask the guy if he knows which os's they support chrome.idle in
edit: actually i found the linux implementation. back from the search results of: CheckIdleStateLocked: http://mxr.mozilla.org/chromium/search?string=CheckIdleStateIsLocked
http://mxr.mozilla.org/chromium/source/src/chrome/browser/idle_linux.cc#24
24 bool CheckIdleStateIsLocked() {
25 // Usually the screensaver is used to lock the screen, so we do not need to
26 // check if the workstation is locked.
27 #if defined(OS_CHROMEOS)
28 return false;
29 #elif defined(USE_OZONE)
30 return false;
31 #else
32 return ScreensaverWindowFinder::ScreensaverWindowExists();
33 #endif
34 }
Leads to ask how is ScreensaverWindowExists we find this: http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc
15 bool ScreensaverWindowFinder::ScreensaverWindowExists() {
16 gfx::X11ErrorTracker err_tracker;
17 ScreensaverWindowFinder finder;
18 ui::EnumerateTopLevelWindows(&finder);
19 return finder.exists_ && !err_tracker.FoundNewError();
20 }
Leads to what is EnumerateTopLevelWindows http://mxr.mozilla.org/chromium/source/src/ui/base/x/x11_util.cc#1059:
1059 void EnumerateTopLevelWindows(ui::EnumerateWindowsDelegate* delegate) {
1060 std::vector<XID> stack;
1061 if (!ui::GetXWindowStack(ui::GetX11RootWindow(), &stack)) {
1062 // Window Manager doesn't support _NET_CLIENT_LIST_STACKING, so fall back
1063 // to old school enumeration of all X windows. Some WMs parent 'top-level'
1064 // windows in unnamed actual top-level windows (ion WM), so extend the
1065 // search depth to all children of top-level windows.
1066 const int kMaxSearchDepth = 1;
1067 ui::EnumerateAllWindows(delegate, kMaxSearchDepth);
1068 return;
1069 }
1070 XMenuList::GetInstance()->InsertMenuWindowXIDs(&stack);
1071
1072 std::vector<XID>::iterator iter;
1073 for (iter = stack.begin(); iter != stack.end(); iter++) {
1074 if (delegate->ShouldStopIterating(*iter))
1075 return;
1076 }
1077 }
1078
We say they call delegate->ShouldStopIterating which was seen in same file as ScreensaverWindowExists: http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc
22 bool ScreensaverWindowFinder::ShouldStopIterating(XID window) {
23 if (!ui::IsWindowVisible(window) || !IsScreensaverWindow(window))
24 return false;
25 exists_ = true;
26 return true;
27 }
Leads to ask what is IsWindowVisible and IsScreensaverWindow
*IsScreensaverWindow, in same file of ScreensaverWindowExists: http://mxr.mozilla.org/chromium/source/src/chrome/browser/screensaver_window_finder_x11.cc
29 bool ScreensaverWindowFinder::IsScreensaverWindow(XID window) const {
30 // It should occupy the full screen.
31 if (!ui::IsX11WindowFullScreen(window))
32 return false;
33
34 // For xscreensaver, the window should have _SCREENSAVER_VERSION property.
35 if (ui::PropertyExists(window, "_SCREENSAVER_VERSION"))
36 return true;
37
38 // For all others, like gnome-screensaver, the window's WM_CLASS property
39 // should contain "screensaver".
40 std::string value;
41 if (!ui::GetStringProperty(window, "WM_CLASS", &value))
42 return false;
43
44 return value.find("screensaver") != std::string::npos;
45 }
IsWindowVisible: http://mxr.mozilla.org/chromium/source/src/ui/base/x/x11_util.cc#546
546 bool IsWindowVisible(XID window) {
547 TRACE_EVENT0("ui", "IsWindowVisible");
548
549 XWindowAttributes win_attributes;
550 if (!XGetWindowAttributes(gfx::GetXDisplay(), window, &win_attributes))
551 return false;
552 if (win_attributes.map_state != IsViewable)
553 return false;
554
555 // Minimized windows are not visible.
556 std::vector<XAtom> wm_states;
557 if (GetAtomArrayProperty(window, "_NET_WM_STATE", &wm_states)) {
558 XAtom hidden_atom = GetAtom("_NET_WM_STATE_HIDDEN");
559 if (std::find(wm_states.begin(), wm_states.end(), hidden_atom) !=
560 wm_states.end()) {
561 return false;
562 }
563 }
Related
Xamarin Forms Debug Build to iPhone from PC Causes Crash
I'm building my first multi-platform app for android and iOS from my PC and have had no issues on the android side. I also have a mac so that I can do the iOS side of things. Set up my Mac via the microsoft guides, have a developer account and did certificates, provisioning, etc. So I start by running the app on the iPhone 13 pro max simulator iOS 15.2 - works flawlessly. The app requires BLE functionality so obviously I can't test everything in the simulator. So I debug to my actual iPhone 13 Pro Max iOS15.2 that's plugged into my PC. App boots up and immediately the UI looks kind of strange, there are weird information display bugs that aren't present in the simulator - which looks as expected. I navigate from the main page to the second page, no issues. From the second page to the 3rd page, immediate crash, no errors, no exceptions. Just this: Native Crash Reporting ================================================================= Got a abrt while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application. ================================================================= ================================================================= Native stacktrace: ================================================================= 0x10446c1e0 - /private/var/containers/Bundle/Application/0EFE911B-4292-432A-B028-6CEB1EFAFB2A/EMBTuner.iOS.app/Xamarin.PreBuilt.iOS : mono_dump_native_crash_info 0x104462c5c - /private/var/containers/Bundle/Application/0EFE911B-4292-432A-B028-6CEB1EFAFB2A/EMBTuner.iOS.app/Xamarin.PreBuilt.iOS : mono_handle_native_crash 0x10446b728 - /private/var/containers/Bundle/Application/0EFE911B-4292-432A-B028-6CEB1EFAFB2A/EMBTuner.iOS.app/Xamarin.PreBuilt.iOS : sigabrt_signal_handler 0x1f2a5ac10 - /usr/lib/system/libsystem_platform.dylib : <redacted> 0x1b8ea45b8 - /usr/lib/system/libsystem_kernel.dylib : <redacted> 0x1b8ea45ec - /usr/lib/system/libsystem_kernel.dylib : <redacted> 0x1e9b35a54 - /System/Library/PrivateFrameworks/TCC.framework/TCC : <redacted> 0x1e9b36230 - /System/Library/PrivateFrameworks/TCC.framework/TCC : <redacted> 0x1e9b32ea8 - /System/Library/PrivateFrameworks/TCC.framework/TCC : <redacted> 0x1f2a9832c - /usr/lib/system/libxpc.dylib : <redacted> 0x1f2a8b85c - /usr/lib/system/libxpc.dylib : <redacted> 0x181b4b6e0 - /usr/lib/system/libdispatch.dylib : <redacted> 0x181b68ec8 - /usr/lib/system/libdispatch.dylib : <redacted> 0x181b5db60 - /usr/lib/system/libdispatch.dylib : <redacted> 0x1f2a6212c - /usr/lib/system/libsystem_pthread.dylib : _pthread_wqthread 0x1f2a61e94 - /usr/lib/system/libsystem_pthread.dylib : start_wqthread ================================================================= Basic Fault Address Reporting ================================================================= Memory around native instruction pointer (0x1b8ea1cf8):0x1b8ea1ce8 ff 0f 5f d6 c0 03 5f d6 30 41 80 d2 01 10 00 d4 .._..._.0A...... 0x1b8ea1cf8 03 01 00 54 7f 23 03 d5 fd 7b bf a9 fd 03 00 91 ...T.#...{...... 0x1b8ea1d08 4f 61 ff 97 bf 03 00 91 fd 7b c1 a8 ff 0f 5f d6 Oa.......{...._. 0x1b8ea1d18 c0 03 5f d6 90 32 80 d2 01 10 00 d4 03 01 00 54 .._..2.........T The app has been terminated. All I'm doing is clicking a button that calls a push navigation in the same exact way that I do from the first page. private async void Choose_Device_Menu_OnClicked(object sender, EventArgs e) { await Navigation.PushAsync(new ListOfDevices(this)); } on appearing section protected override void OnAppearing() { base.OnAppearing(); } Contructor section namespace EMBTuner { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class ListOfDevices : ContentPage { private readonly IDeviceManipulationPage _page; public ObservableCollection<IBacGenericDevice> Items { get; set; } = new ObservableCollection<IBacGenericDevice>(BacCommunication.CurrentRepository.BacDevices); public ListOfDevices(IDeviceManipulationPage page) { InitializeComponent(); _page = page; } ... } } Again, it's very strange since this works perfectly on the simulator. SOLUTION: Adding BLE permissions within info.plist fixed the error. Wish the debugger was a bit smarter in this situation...
Get GDI HFONT line height as interpreted by DrawText[Ex]
I want to know which metrics are used to calculate the correct line height (vertical distance between the baselines of 2 adjacent lines of text). "Correct" shall arbitrarily defined as "whatever DrawTextW does". The accepted answer here appears to follow what the graph provided in this MSDN article says: TEXTMETRICW.tmHeight + TEXTMETRICW.tmExternalLeading; But that does not appear to be correct. Some testing with 2 pieces of text, each of which consists of 2 lines: // RECT rc is more than large enough to fit any text int HeightChinese = DrawTextW(hdc, L"中\r\n文", -1, &rc, 0); int HeightLatin = DrawTextW(hdc, L"Latin,\r\nlatin!", -1, &rc, 0); The expected return values should be 2 * <SomethingUnknown>. One observation is that the return value of DrawTextW will always match the RECT output if DT_CALCRECT were used, for all fonts that I have on my machine. So I will assume that using DT_CALCRECT does not provide any additional value over using the return value of DrawTextW. For all fonts on my machine, these are true: HeightChinese == HeightLatin LOGFONTW.lfHeight == TEXTMETRICW.tmHeight (1). For most fonts on my machine, this is true: HeightXxx == 2 * TEXTMETRICW.tmHeight Which already contradicts the formula provided in the other question (TEXTMETRICW.tmExternalLeading does not play a role). For example, "Arial" with LOGFONTW.lfHeight = 36 will have TEXTMETRICW.tmExternalLeading = 1, and HeightXxx == 72 (not 74). The distance between the lines when taking a screenshot and measuing the pixels is also 72 (so it appears that the return value can be trusted). At the same time, "Segoe UI" with LOGFONTW.lHeight = 43 will have TEXTMETRICW.tmExternalLeading = 0, and HeightXxx == 84 (not 86). This is a list of all anomalous fonts on my system: "FontName" -- "DrawText return value" vs "2 * TEXTMETRICW.tmHeight" Ebrima -- 84 vs 86 Leelawadee UI -- 84 vs 86 Leelawadee UI Semilight -- 84 vs 86 Lucida Sans Unicode -- 96 vs 98 Malgun Gothic -- 84 vs 86 Malgun Gothic Semilight -- 84 vs 86 Microsoft Tai Le -- 80 vs 82 Microsoft YaHei -- 82 vs 84 Microsoft YaHei UI Light -- 82 vs 84 MS Gothic -- 66 vs 64 MS UI Gothic -- 66 vs 64 MS PGothic -- 66 vs 64 Nirmala UI -- 84 vs 86 Nirmala UI Semilight -- 84 vs 86 Palatino Linotype -- 84 vs 86 Segoe UI -- 84 vs 86 Segoe UI Black -- 84 vs 86 Segoe UI Historic -- 84 vs 86 Segoe UI Light -- 84 vs 86 Segoe UI Semibold -- 84 vs 86 Segoe UI Semilight -- 84 vs 86 Segoe UI Symbol -- 84 vs 86 SimSun -- 66 vs 64 NSimSun -- 66 vs 64 SimSun-ExtB -- 66 vs 64 Verdana -- 76 vs 78 Webdings -- 62 vs 64 Yu Gothic UI -- 84 vs 86 Yu Gothic UI Semibold -- 84 vs 86 Yu Gothic UI Light -- 84 vs 86 Yu Gothic UI Semilight -- 84 vs 86 MS Mincho -- 66 vs 64 MS PMincho -- 66 vs 64 Ubuntu Mono -- 62 vs 64 Sometimes the return value is 2 bigger, sometimes it is 2 smaller than the calculated value. I have looked at the other values in TEXTMETRICW, and I've also looked at the extra data available int OUTLINETEXTMETRICW, but I could not find any pattern that would explain the observations. So then, what are the correct metrics to calculate line height? I understand that I could call DrawTextW with DT_CALCRECT to get this value, but I want to understand where this information comes from (and thus, how a font designer could control it in a predictable way). Here is a gist with a complete Windows application that demonstrates this. All the interesting stuff is in WM_PAINT. Search for #EDIT for some interesting code switches and breakpoints. At the time of posting this question, my GitHub account has been flagged, and the Gist is temporarily unavailable. I hope this can be resolved quickly. (1) I am using EnumFontFamiliesEx to enumerate all fonts, and it happens to provide LOGFONTW structs with positive lfHeight values. That means I am using cell height rather than character height. While character height is the more typical way of specifying font height, that is sort of irrelevant here, it just so happens that cell height is equal to TEXTMETRICW.tmHeight, but character height isn't. The relevant value for calculations is TEXTMETRICW.tmHeight, and not LOGFONTW.lfHeight.
As Jonathan Potter pointed out, the formula TEXTMETRICW.tmHeight should have been correct, and if the DT_EXTERNALLEADING flag is set, then it's TEXTMETRICW.tmHeight + TEXTMETRICW.tmExternalLeading. I reverse-engineered DrawTextExW with Ghidra and the reason the numbers were sometimes off is not DrawTextExW itself. DrawTextExW internally uses a DT_InitDrawTextInfo, which in turn uses GetTextMetricsW and calculates the line height according to the above formula. However, consider this code to probe all fonts: LOGFONTW Probe = {}; Probe.lfCharSet = DEFAULT_CHARSET; EnumFontFamiliesExW(hdc, &Probe, InitializeFontInfo_EnumFontFamiliesCallback, NULL, 0); static int CALLBACK InitializeFontInfo_EnumFontFamiliesCallback(const LOGFONTW *LogFont, const TEXTMETRICW *TextMetric, DWORD FontType, LPARAM lParam) { FONT_INFO tmp = {}; tmp.LogFont = *LogFont; tmp.TextMetric = *TextMetric; FontInfo.push_back(tmp); return 1; } Here, for the Segoe UI font, for example, LogFont->lfHeight will be 43. And so, TextMetric->tmHeight will also be 43, which, you would think, makes sense to some degree. However: If you go ahead and select this LogFont into a HDC, and then use GetTextMetricsW, like so: HFONT Font = CreateFontIndirectW(LogFont); SelectObject(hdc, Font); TEXTMETRICW TextMetric = {}; GetTextMetricsW(hdc, &TextMetric); Then TextMetric->tmHeight == 42 even though LogFont->lfHeight == 43. In other words, the values provided to the EnumFontFamiliesExW callback for its TEXTMETRICW parameter cannot be trusted. Although you could argue that the bug is elsewhere, and selecting a LogFont->lfHeight == 43 font should really also produce a TextMetric->tmHeight == 43 text metric, but I suppose that's too much to ask. My guess is that there's a floating point conversion going on somewhere in there, and that occasionally produces a rounding error for some numbers.
DrawText() only uses TEXTMETRIC.tmExternalLeading if the DT_EXTERNALLEADING flag is set when you call it - you don't seem to have taken that into account. The line height formula is basically: int iLineHeight = tm.tmHeight + ((format & DT_EXTERNALLEADING) ? tm.tmExternalLeading : 0);
NSDrawer causes crash when added to App Window
I'm trying to programmatically add an NSDrawer to my app's main window (which also has an NSOutlineViewwhich was setup in IB): Ivar: var dd: NSDrawer? = nil Then, when a disclosure triangle button is clicked: if dd == nil { var drawer_rect = NSInsetRect(self.window.frame, 30, 30).size drawer_rect.height = 150 dd = NSDrawer.init(contentSize: drawer_rect, preferredEdge: NSRectEdge.minY) dd!.contentView = self.status_scroll dd!.parentWindow = self.window } So when the user tries to 'disclose' the drawer, the above code creates an NSDrawer and then displays it. It all works fine but Xcode dumps the following out as the parentWindow is set: [General] ERROR: Setting <NSOutlineView: 0x100f0b9b0> as the first responder for window <NSDrawerWindow: 0x100fc8900>, but it is in a different window (<NSWindow: 0x6080001e0600>)! This would eventually crash when the view is freed. The first responder will be set to nil. ( 0 AppKit 0x00007fff9fc289cf -[NSWindow _validateFirstResponder:] + 557 1 AppKit 0x00007fff9f3a374c -[NSWindow _setFirstResponder:] + 31 2 AppKit 0x00007fff9f90c35b -[NSDrawerWindow _setParentWindow:] + 64 3 AppKit 0x00007fff9f90b666 -[NSDrawer(DrawerInternals) _doSetParentWindow:] + 382 4 AppKit 0x00007fff9f907786 -[NSDrawer setParentWindow:] + 78 Comment out the setting of the parentWindow and nothing gets dumped to the console.
NSDrawer is deprecated as per Apple documentation. You should consider a different design. If you still use NSDrawer, you may face such issues.
AVMutableVideoComposition - CoreAnimation: warning, deleted thread with uncommitted CATransaction
I am working on some basic video compositions using AVMutableComposition - currently a video layer (AVMutableVideoComposition) with a text layer (CATextLayer). It all looks ok but when I let it export via "AVMutableComposition exportAsynchronouslyWithCompletionHandler " it goes off and completes but returns this error: CoreAnimation: warning, deleted thread with uncommitted CATransaction; created by: 0 QuartzCore 0x00007fff8a106959 _ZN2CA11Transaction4pushEv + 219 1 QuartzCore 0x00007fff8a106531 _ZN2CA11Transaction15ensure_implicitEv + 273 2 QuartzCore 0x00007fff8a10d66f _ZN2CA5Layer13thread_flags_EPNS_11TransactionE + 37 3 QuartzCore 0x00007fff8a10d5a7 _ZN2CA5Layer4markEPNS_11TransactionEjj + 79 4 QuartzCore 0x00007fff8a112cac _ZN2CA5Layer27contents_visibility_changedEPNS_11TransactionEb + 216 5 QuartzCore 0x00007fff8a112b65 _ZN2CA5Layer12mark_visibleEPNS_11TransactionEb + 261 6 QuartzCore 0x00007fff8a112b26 _ZN2CA5Layer12mark_visibleEPNS_11TransactionEb + 198 7 QuartzCore 0x00007fff8a112b26 _ZN2CA5Layer12mark_visibleEPNS_11TransactionEb + 198 8 QuartzCore 0x00007fff8a1128d1 _ZN2CA5Layer11set_visibleEj + 335 9 QuartzCore 0x00007fff8a1126b9 _ZN2CA7Context9set_layerEPKv + 75 10 MediaToolbox 0x00007fff857f155b FigCoreAnimationRendererInvalidate + 108 11 CoreFoundation 0x00007fff8ec763df CFRelease + 511 12 MediaToolbox 0x00007fff857d3a6b FigVideoCompositionProcessorInvalidate + 675 13 MediaToolbox 0x00007fff85791341 FigAssetWriterCreateWithURL + 18573 14 MediaToolbox 0x00007fff85791f7b FigAssetWriterCreateWithURL + 21703 15 CoreMediaAuthoringCrunchers 0x00000001046e2b99 AssetAudioSourcer_CreateInstance + 3865 I find that this goes away if I comment-out the following line - however the CATextLayer is not rendered: videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; Any thoughts anyone? Adam
You must ensure any UI drawing occurs on the main thread. The line you commented out probably does some drawing internally, so you want to make sure this code is executed on the main thread. A couple ways to do this is by using the function dispatch_async() or the methods performSelectorOnMainThread:withObject:waitUntilDone: or performSelectorOnMainThread:withObject:waitUntilDone:modes: - (void) someMethod { // You may need to load a container object to pass as myCustomData whose // contents you then access in myCustomDrawing: if the data isn't accessible // as instance data. [...] // Perform all drawing/UI updates on the main thread. [self performSelectorOnMainThread:#selector(myCustomDrawing:) withObject:myCustomData waitUntilDone:YES]; [...] } - (void) myCustomDrawing:(id)myCustomData { // Perform any drawing/UI updates here. videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; } For a related post on the difference between dispatch_async() and performSelectorOnMainThread:withObjects:waitUntilDone: see Whats the difference between performSelectorOnMainThread and dispatch_async on main queue?
NSWorkspace setIcon:forFile:options: crashes
I am facing crash sometimes on [NSWorkspace setIcon:forFile:options:] API. any help is appreciated. here is crash stack, 0 libsystem_kernel.dylib 0x00007fff85bfbe56 __semwait_signal_nocancel + 10 1 libsystem_c.dylib 0x00007fff8c04818b nanosleep$NOCANCEL + 139 2 libsystem_c.dylib 0x00007fff8bfe7c78 usleep$NOCANCEL + 53 3 libsystem_c.dylib 0x00007fff8bfe7aa6 abort + 187 4 libsystem_c.dylib 0x00007fff8c04684c free + 389 5 com.apple.CoreServices.CarbonCore 0x00007fff8df7aaf7 CSMemDisposePtr + 23 6 com.apple.CoreServices.CarbonCore 0x00007fff8df7aaba CSMemDisposeHandle + 79 7 com.apple.CoreServices.CarbonCore 0x00007fff8df7c355 DisposeHandle + 9 8 com.apple.AppKit 0x00007fff90356598 -[NSWorkspace setIcon:forFile:options:] + 566 Here is code, static NSImage *FolderIcon = nil; if(!FolderIcon) { FolderIcon = [[NSImage imageNamed:#"xxx.icns"] retain]; } if(![[NSWorkspace sharedWorkspace] setIcon: FolderIcon forFile:Path options:0]) { NSLog(#"error"); } I am using static icon, so I don't think possibility of dangling pointer, Also I checked if we pass file path which does not exists then it return "NO". But it is not crashing. This is rarely re-producible.. will paste errors once it re-produce
You should not call -setIcon:forFile:options: from multiple thread at a time. From Documentation: It is safe to call this method from any of your app’s threads, but you must call it from only one thread at a time.