How to know whether a window is minimised or not? - macos

I'd like to know which windows are visible on screen. CGWindowListCopyWindowInfo gives me the list of windows, which is great except it also lists minimised windows as well.
I tried to use kCGWindowIsOnscreen to detect hidden/minimised windows but it always give TRUE for all windows. Is there any way to detect that somehow?
- (void) checkWindows {
NSMutableArray *windows = (__bridge NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
for (NSDictionary *window in windows) {
NSString *owner = [window objectForKey:#"kCGWindowOwnerName" ];
NSString *name = [window objectForKey:#"kCGWindowName" ];
CFBooleanRef visibleBR = (CFBooleanRef)[window objectForKey:#"kCGWindowIsOnscreen"];
bool visible = CFBooleanGetValue(visibleBR);
NSLog(#"%#,%#,Visible:%#",owner,name,visible?#"YES":#"NO");
}
}
UPDATE: very strange, it's only Microsoft word. In fact it doesn't have to be hidden, Word creates a full screen window which is not visible but listed among the visible windows.

The issue was caused by MS Word.
It creates a full screen window which is not visible but listed among the visible windows. CGWindowListCopyWindowInfo lists visible/minimised windows correctly.

Related

tvOS 14.3 UISearchController: How to locked in display

Short version, is there a way to make this 14.3 look
into this prior to 14.3
Long version,
In every OS iteration the look of the UISearchController is changing. Before it only change the keyboard portion but with 14.3 it changed that the keyboard portion is on left side while the search results are on the right, which is what we don't like since we have custom view and overlays on top of it.
Any APIs to make it revert to the previous iteration, that is the keyboard are all within one horizontal line and search results on bottom, and stay that way forever?
Here's the code for the integration. The 14.3 UI look did mess up the app overall.
_searchResults = [[UITableViewController alloc] init];
_searchController = [[UISearchController alloc] initWithSearchResultsController:_searchResults];
_searchController.searchResultsUpdater = self;
_searchController.view.backgroundColor = [UIColor clearColor];
_searchController.searchBar.keyboardAppearance = UIKeyboardAppearanceDark;
_searchController.searchBar.placeholder = #"TV Shows, Movies, Keywords";
_searchController.obscuresBackgroundDuringPresentation = false;
_searchController.hidesNavigationBarDuringPresentation = true;
_searchContainer = [[UISearchContainerViewController alloc] initWithSearchController:_searchController];
_navController = [[UINavigationController alloc] initWithRootViewController:_searchContainer];
[_navController willMoveToParentViewController:self];
[self addChildViewController:_navController];
[self.view addSubview:_navController.view];
There is no code to change keyboard looking but it's simply changed on your device setting:
Settings>General>Keyboard = Auto
but you can changed to "Linear" or "Grid"
for more information see the video:
Discover search suggestions for Apple TV

NSOpenPanel breaks my SDL/OpenGL app

I'm making a small SDL/OpenGL game, in which the user can select a map/level by using the cocoa open file-dialog (NSOpenPanel). However, when doing so, I get the error "invalid frame-buffer operation" upon every glClear. When I get the status of the frame buffer (using glCheckFramebufferStatus) it's GL_FRAMEBUFFER_UNDEFINED (0x8219). I also noticed that I do not need to present the open panel (using runModal), but only to create it, for the error to occur. It is possible to create it before the SDL_SetVideoMode, but not thereafter. Strangely, the NSSavePanel doesn't cause these issues at all. Any ideas?
Edit: Added some code to show a stripped down test-init method:
SDL_Init( SDL_INIT_VIDEO );
m_pScreen = SDL_SetVideoMode( 800, 600, 32, SDL_OPENGL );
// this section causes the problem. Works well if I change the NSOpenPanel to a NSSavePanel
#autoreleasepool {
NSOpenPanel *openPanel = [[NSOpenPanel openPanel] retain];
[openPanel runModal];
[openPanel release];
}
int number = glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(number == GL_FRAMEBUFFER_COMPLETE); // crash here
This usually happens because there's no current context. The OS-supplied code like NSOpenPanel can sometimes change the current OpenGL context, or leave the current context as undefined. You must make sure that you set the context back to the one you're drawing to when this happens. I hit this same problem in some code I'm working on last week! :-)
After some more testing (and reading the previous answers) I found a solution which works for me:
#autoreleasepool {
NSOpenGLContext *foo = [NSOpenGLContext currentContext];
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel runModal];
[foo makeCurrentContext];
}
To work around this oddity I had to reset my view with SDL_SetVideoMode if frame buffer status != GL_FRAMEBUFFER_COMPLETE

How to get the frame (origin, Size) of every visible windows on the active space?

I'm trying to figure out how to get the frame of all visible windows.
I tried the following code, but it only works for the app itself other windows report {0,0,0,0}
NSArray *windowArray = [NSWindow windowNumbersWithOptions:NSWindowNumberListAllApplications | NSWindowNumberListAllSpaces];
for(NSNumber *number in windowArray){
NSLog(#"Window number: %#", number);
NSWindow *window = [[NSApplication sharedApplication] windowWithWindowNumber:[number intValue]];
NSLog(#"Window: %#", NSStringFromRect( [[window contentView] frame]));
}
Sample code is appreciated.
I figured it out:
NSMutableArray *windows = (__bridge NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
for (NSDictionary *window in windows) {
NSString *name = [window objectForKey:#"kCGWindowName" ];
CGRect bounds;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:#"kCGWindowBounds"], &bounds);
NSLog(#"%#: %#",name,NSStringFromRect(bounds));
}
You can't create an NSWindow for a window of another application. In general, you can't access the objects of other applications except through an interface that they cooperate with, like scripting.
You can get what you're looking for using the Quartz Window Services (a.k.a. CGWindowList) API.
I'm not at all sure that the window numbers returned by Cocoa are the same as the window numbers used by that API. In fact, the docs for -[NSWindow windowNumber] specifically say "note that this isn’t the same as the global window number assigned by the window server". I'm note sure to what use you can put the window numbers returned by +[NSWindow windowNumbersWithOptions:] which are not for your application's windows.

How do I get "Page Attributes" option in Cocoa print dialog?

The program I'm writing runs under OS X 10.5 Leopard. My target has its Base SDK and Deployment Target both set to Mac OS X 10.5. When I initiate printing, my print dialog doesn't show the Page Attributes option in which the user can select page size and orientation.
Other programs running under Leopard do show this option:
Here's the code that initiates printing:
-(void)print {
NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
TemperaturePressurePrintView *printView = [[TemperaturePressurePrintView alloc] initWithFrequencies:frequencies];
if (printView) {
[[NSPrintOperation printOperationWithView:printView printInfo:printInfo] runOperation];
[printView release];
}
}
What do I need to do to get Page Attributes to show up in my print dialog?
This was a tough thing to search for because the results were mostly about using the print panel, not programming one. I finally found a clue on Cocoabuilder where it mentions NSPrintPanelOptions and NSPrintPanel's -setOptions: method.
This code accomplishes what I need:
-(void)print {
NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
TemperaturePressurePrintView *printView = [[TemperaturePressurePrintView alloc] initWithFrequencies:frequencies];
if (printView) {
NSPrintOperation *op = [NSPrintOperation printOperationWithView:printView printInfo:printInfo];
[[op printPanel] setOptions:[[op printPanel] options] | NSPrintPanelShowsPageSetupAccessory];
[op runOperation];
[printView release];
}
}
It's a few years after the original answer and macOS Sierra seems to have introduced a bug into the behaviour of panels that have the 'NSPrintPanelShowsPageSetupAccessory' option set. Invalid values, such as a ridiculously large scale, cause crashes instead of displaying an alert sheet.
Fortunately there is a workaround. Using
NSPrintPanelShowsPaperSize | NSPrintPanelShowsOrientation | NSPrintPanelShowsScaling
instead seems to result in a panel that works fine.

How to obtain info of the program from the window list with CGWindowListCopyWindowInfo

I managed to get list of windows on the desktop with CGWindowListCopyWindowInfo, but the next time is to try to get the properties of the window, like the program name, title, and other properties.
What API should I look into and do we have any example on how to do this?
List the windows and retrieve the specific information while looping through:
NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
for (NSDictionary *window in windows) {
NSString *owner = [window objectForKey:#"kCGWindowOwnerName" ];
NSString *name = [window objectForKey:#"kCGWindowName" ];
NSLog(#"%# - %#",owner,name);
}
Available keys:
kCGWindowIsOnscreen
kCGWindowLayer
kCGWindowMemoryUsage
kCGWindowName
kCGWindowNumber
kCGWindowOwnerName
kCGWindowOwnerPID
kCGWindowSharingState
kCGWindowStoreType

Resources