iswiftapp / iswift

Objective-C to Swift Converter
30 stars 3 forks source link

Error - CGWindowID win_id = [[windowDict objectForKey:(id)kCGWindowNumber] intValue]; #203

Closed gerasimsergey closed 6 years ago

gerasimsergey commented 6 years ago

Hi, I'm trying your application before buying and immediately on the test case I got an error CGWindowID win_id = [[windowDict objectForKey:(id)kCGWindowNumber] intValue];

https://cl.ly/042p2Q2x3M1J

drkameleon commented 6 years ago

Hi,

Can you please cp-paste the whole piece of code and/or the exact error message for the marked line?

gerasimsergey commented 6 years ago

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "CGWindow.h"

#include <CoreFoundation/CFBase.h>
#include <CoreFoundation/CFAvailability.h>
#include <stdint.h>

@class Window;
@implementation aClass

-(NSMenu*) dockMenuForItem {
    NSMenu *menu = [[NSMenu alloc] init];
    NSInteger i = 0;

    [menu insertItem:[NSMenuItem separatorItem] atIndex:i++];

    [self constructActiveDockMenu:menu atIndex: i++];
    [menu insertItem:[NSMenuItem separatorItem] atIndex:i++];

    NSMenuItem *item1;
    if (app.isHidden) {
        item1 = [menu insertItemWithTitle:NSLocalizedString(@"Show", @"")
                                   action:nil keyEquivalent:@"" atIndex:i++];
    } else {
        item1 = [menu insertItemWithTitle:NSLocalizedString(@"Hide", @"")
                                   action:nil keyEquivalent:@"" atIndex:i++];
    }
    [menu insertItem:[NSMenuItem separatorItem] atIndex:i++];

    return menu;
}

-(NSArray*) windowsList {
    NSMutableArray *windowList = [[NSMutableArray alloc] init];

    CGWindowListOption option = kCGWindowListOptionAll;
    option |= kCGWindowListOptionOnScreenOnly;
    option |= kCGWindowListExcludeDesktopElements;

    CFArrayRef cgWindowList = CGWindowListCopyWindowInfo(option, kCGNullWindowID);

    for (NSMutableDictionary* dict in (__bridge NSArray*)cgWindowList) {
        int pid = [[dict objectForKey:(id)kCGWindowOwnerPID] intValue];
        if (pid == self.pid) {
            if ([[dict objectForKey:(id)kCGWindowLayer] intValue]> 1000) {
                continue;
            }

            NSString *windowName = [[dict objectForKey:(id)kCGWindowName] description];
            if ([windowName isEqualToString:@""] || windowName == nil)
                continue;

            Window *window = [self createWindow:dict];
            [windowList addObject: window];
        }
    }

    return [windowList copy];
}

- (void)createWindow:(NSMutableDictionary*) windowDict    {
    int pid = [[windowDict objectForKey:(id)kCGWindowOwnerPID] intValue];
    CGWindowID win_id = [[windowDict objectForKey:(id)kCGWindowNumber] intValue];
    NSString *windowName = [[windowDict objectForKey:(id)kCGWindowName] description];
    Window *window = [[Window alloc] init];
    window.title = windowName;
    window.accessibilityElement = [self AXUIElementRefByWinId:win_id pid:pid];
    window.application = self;

    CGImageRef cgImage = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, win_id, kCGWindowImageDefault);
    NSSize size = NSMakeSize(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage));
    NSImage *image = [[NSImage alloc] initWithCGImage:cgImage size:size];
    window.previewImage  = image;

}

@end
gerasimsergey commented 6 years ago

https://cl.ly/0h1y3Y2f460z

drkameleon commented 6 years ago

To get past this (first) error @ line 38, you'll have to somehow define the unknown (for the compiler) type: CGWindowListOption. An idea/hack would be to include a class declaration at the top of the file, like @class CGWindowListOption;

@ line 44, delete the __bridge specifier. It's not yet - fully - recognized.

And for the error that'll show @ line 66 (re: CGWindowId), proceed as in the first hack: by adding a @class CGWindowId; line at the top of the file.

And - yep, with a couple of hacks - it works.

Input

#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "CGWindow.h"

#include <CoreFoundation/CFBase.h>
#include <CoreFoundation/CFAvailability.h>
#include <stdint.h>

@class Window;
@class CGWindowListOption;
@class CGWindowID;
@implementation aClass

-(NSMenu*) dockMenuForItem {
    NSMenu *menu = [[NSMenu alloc] init];
    NSInteger i = 0;

    [menu insertItem:[NSMenuItem separatorItem] atIndex:i++];

    [self constructActiveDockMenu:menu atIndex: i++];
    [menu insertItem:[NSMenuItem separatorItem] atIndex:i++];

    NSMenuItem *item1;
    if (app.isHidden) {
        item1 = [menu insertItemWithTitle:NSLocalizedString(@"Show", @"")
                                   action:nil keyEquivalent:@"" atIndex:i++];
    } else {
        item1 = [menu insertItemWithTitle:NSLocalizedString(@"Hide", @"")
                                   action:nil keyEquivalent:@"" atIndex:i++];
    }
    [menu insertItem:[NSMenuItem separatorItem] atIndex:i++];

    return menu;
}

-(NSArray*) windowsList {
    NSMutableArray *windowList = [[NSMutableArray alloc] init];

    CGWindowListOption* option = kCGWindowListOptionAll;
    option |= kCGWindowListOptionOnScreenOnly;
    option |= kCGWindowListExcludeDesktopElements;

    CFArrayRef cgWindowList = CGWindowListCopyWindowInfo(option, kCGNullWindowID);

    for (NSMutableDictionary* dict in (NSArray*)cgWindowList) {
        int pid = [[dict objectForKey:(id)kCGWindowOwnerPID] intValue];
        if (pid == self.pid) {
            if ([[dict objectForKey:(id)kCGWindowLayer] intValue]> 1000) {
                continue;
            }

            NSString *windowName = [[dict objectForKey:(id)kCGWindowName] description];
            if ([windowName isEqualToString:@""] || windowName == nil)
                continue;

            Window *window = [self createWindow:dict];
            [windowList addObject: window];
        }
    }

    return [windowList copy];
}

- (void)createWindow:(NSMutableDictionary*) windowDict    {
    int pid = [[windowDict objectForKey:(id)kCGWindowOwnerPID] intValue];
    CGWindowID win_id = [[windowDict objectForKey:(id)kCGWindowNumber] intValue];
    NSString *windowName = [[windowDict objectForKey:(id)kCGWindowName] description];
    Window *window = [[Window alloc] init];
    window.title = windowName;
    window.accessibilityElement = [self AXUIElementRefByWinId:win_id pid:pid];
    window.application = self;

    CGImageRef cgImage = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, win_id, kCGWindowImageDefault);
    NSSize size = NSMakeSize(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage));
    NSImage *image = [[NSImage alloc] initWithCGImage:cgImage size:size];
    window.previewImage  = image;

}

@end

Output

import Foundation
import Cocoa
import CGWindow

class aClass {

    func dockMenuForItem() -> NSMenu {
        var menu: NSMenu = NSMenu()
        var i: Int = 0
        menu.insertItem(NSMenuItem.separatorItem(), at: i++)
        self.constructActiveDockMenu(menu, atIndex: i++)
        menu.insertItem(NSMenuItem.separatorItem(), at: i++)
        var item1: NSMenuItem
        if app.isHidden {
            item1 = menu.insertItem(withTitle: NSLocalizedString("Show", ""), action: nil, keyEquivalent: "", at: i++)
        } else {
            item1 = menu.insertItem(withTitle: NSLocalizedString("Hide", ""), action: nil, keyEquivalent: "", at: i++)

        }
        menu.insertItem(NSMenuItem.separatorItem(), at: i++)
        return menu
    }

    func windowsList() -> [AnyObject] {
        var windowList: NSMutableArray = NSMutableArray()
        var option: CGWindowListOption = kCGWindowListOptionAll
        option |= kCGWindowListOptionOnScreenOnly
        option |= kCGWindowListExcludeDesktopElements
        var cgWindowList: CFArrayRef = CGWindowListCopyWindowInfo(option, kCGNullWindowID)
        for dict in (cgWindowList as? [AnyObject]) {
            var pid: Int32 = dict.object(forKey: (kCGWindowOwnerPID as? Any)).int32Value
            if pid == self.pid {
                if dict.object(forKey: (kCGWindowLayer as? Any)).int32Value > 1000 {
                    continue
                }
                var windowName: String = dict.object(forKey: (kCGWindowName as? Any)).description()
                if windowName.isEqual(to: "") || windowName == nil {
                    continue
                }
                var window: Window = self.createWindow(dict)
                windowList.addObject(window)
            }
        }
        return windowList.copy()
    }

    func createWindow(_ windowDict: NSMutableDictionary) {
        var pid: Int32 = windowDict.object(forKey: (kCGWindowOwnerPID as? Any)).int32Value
        var win_id: CGWindowID = windowDict.object(forKey: (kCGWindowNumber as? Any)).int32Value
        var windowName: String = windowDict.object(forKey: (kCGWindowName as? Any)).description()
        var window: Window = Window()
        window.title = windowName
        window.accessibilityElement = self.AXUIElementRefByWinId(win_id, pid: pid)
        window.application = self
        var cgImage: CGImageRef = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, win_id, kCGWindowImageDefault)
        var size: NSSize = NSMakeSize(CGImageGetWidth(cgImage), CGImageGetHeight(cgImage))
        var image: NSImage = NSImage(cgimage: cgImage, size: size)
        window.previewImage = image
    }

}
gerasimsergey commented 6 years ago

well, a little bit of course hack ... I think I should try a few more real files when I start switching to Swift