www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Drawing Native OSX Windows with D

reply Mike McKee <volomike gmail.com> writes:
Does anyone have a demo that shows how I can call the native OSX 
API to draw a basic window that's minimizable and can be closed?

I was thinking of making an installer for the Mac, you see. So 
for instance, people would download a very thin .app file and run 
that. Because it only uses native window APIs on OSX, it wouldn't 
be a huge download. That way, this installer can then download 
the larger payload of my Qt/C++ application that I composed.
Nov 28 2015
next sibling parent Guillaume Piolat <first.last gmail.com> writes:
On Saturday, 28 November 2015 at 10:40:19 UTC, Mike McKee wrote:
 Does anyone have a demo that shows how I can call the native 
 OSX API to draw a basic window that's minimizable and can be 
 closed?

 I was thinking of making an installer for the Mac, you see. So 
 for instance, people would download a very thin .app file and 
 run that. Because it only uses native window APIs on OSX, it 
 wouldn't be a huge download. That way, this installer can then 
 download the larger payload of my Qt/C++ application that I 
 composed.
https://github.com/p0nce/DerelictCocoa/tree/master/examples/window
Nov 28 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-11-28 11:40, Mike McKee wrote:
 Does anyone have a demo that shows how I can call the native OSX API to
 draw a basic window that's minimizable and can be closed?

 I was thinking of making an installer for the Mac, you see. So for
 instance, people would download a very thin .app file and run that.
 Because it only uses native window APIs on OSX, it wouldn't be a huge
 download. That way, this installer can then download the larger payload
 of my Qt/C++ application that I composed.
The recommend ways of distributing applications on OS X, in the preferred order, are: 1. App Store 2. DMG containing an application bundle 3. Native installer 4. Other ways Building an application that acts like an installer would fall under number 4, that last preferred way. If you can't/don't want to go with the App Store then why not the second option? -- /Jacob Carlborg
Nov 28 2015
parent reply Mike McKee <volomike gmail.com> writes:
On Saturday, 28 November 2015 at 14:05:37 UTC, Jacob Carlborg 
wrote:
 If you can't/don't want to go with the App Store then why not 
 the second option?
I'm coding an antivirus application for the Mac, using a third-party antivirus engine, in Qt/C++. It needs some things to run under high privileges. As far as I know, you can't do that with a DMG package, but can do it with a PKG package. I've learned a tremendous amount about PKG packages (the docs are difficult), but the one thing that doesn't seem possible is to download a component from a remote URL with it except via a Perl or Bash script. The PKG flat format supports a way to call a preinstall and postinstall Perl or Bash script. The trouble with that technique, however, is that if you have a 30MB download that takes awhile, the installer screen sits at "Running Package Scripts..." for like 3 minutes (on 2Mbps DSL) and this can confuse the consumer into thinking the installer is hung up, when it isn't. The thing I'd like to achieve with D is to have my Bash or Perl script call a command line D application that finds the current installer window x,y, hides the Cocoa-based window, draws my new Cocoa-based window to replace it at the same x,y,w,h as the other one, and then runs curl command to download the file, then uses the D application again to stop showing my custom window, unhide the installer window, and exit the Bash script. So, some things I need to learn in D: * How to enumerate the currently visible Cocoa windows and their titles or internal names, along with their window handle. * How to get the x,y of an existing Cocoa window by its window handle. * How to hide a Cocoa window by its window handle. * How to draw my own Cocoa window at an x,y coordinate. * How to destroy my Cocoa window by its window handle. * How to unhide a previously hidden Cocoa window by its window handle. If I could pull this off -- I'd make a really nice OSX installer because I could have a small pkg file that downloads and runs, and then its window gets hidden and shows a more-user friendly window (drawn in D and Cocoa) to let the consumer know it's downloading a larger file, and then show the conclusion when done. Currently nothing like that exists on OSX, but does exist on Windows via the Inno Setup and InstallShield platforms.
Nov 28 2015
next sibling parent reply Mike McKee <volomike gmail.com> writes:
A few interesting things here. I tried to do these things via the 
new Apple language, Swift.

* You can enum windows, but unlike Microsoft Windows, you have no 
permissions to hide a window. BTW, hiding a window is a window 
object method called orderOut(nil), and they only permit it on 
your own windows, not another application's windows. However, 
that said, there's a neat AppleScript technique that seems to 
work in hiding the entire application, rather than just the 
window.

osascript -e "tell application "System Events" to set visible of 
process "Installer" to false'

* You can enum Cocoa windows and get x,y,w,h, process ID, window 
name, and window number (I guess that's an ID) on each. Here's 
the technique in Swift:

     import Foundation;
     import Cocoa;

     let windows = CGWindowListCopyWindowInfo(
         CGWindowListOption.OptionOnScreenOnly,
         CGWindowID(0))! as NSArray;
     for var i = 0; i < windows.count; i++  {
         let window = windows[i];
         let owner = window["kCGWindowOwnerName"] as! String;
         if owner != "Installer" {
             continue;
         }
        // do something with your window object here
     }

I don't know how to do this in D, but came up with a workaround. 
My pkg installer will run a Bash script which will hide the 
Installer window via osascript, show a window that I drew with 
Swift that basically tells people to wait because it's 
downloading components, runs curl to download the payload from 
the server and copy it into the appropriate places (as well as 
set up system library stuff as needed), and then hide my custom 
Swift window (the progress window), and then uses osascript again 
to unhide the installer application.
Nov 29 2015
parent Jacob Carlborg <doob me.com> writes:
On 2015-11-29 09:03, Mike McKee wrote:
 A few interesting things here. I tried to do these things via the new
 Apple language, Swift.

 * You can enum windows, but unlike Microsoft Windows, you have no
 permissions to hide a window. BTW, hiding a window is a window object
 method called orderOut(nil), and they only permit it on your own
 windows, not another application's windows. However, that said, there's
 a neat AppleScript technique that seems to work in hiding the entire
 application, rather than just the window.
There are applications like Moom [1] that lets you control the size and position of the windows of other applications, not sure about hiding windows though. I'm not entirely sure how they work but they require accessibility to be enabled (System Preferences -> Security & Privacy -> Privacy -> Accessibility). [1] https://manytricks.com/moom/ -- /Jacob Carlborg
Nov 29 2015
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-11-29 03:30, Mike McKee wrote:

 I'm coding an antivirus application for the Mac, using a third-party
 antivirus engine, in Qt/C++. It needs some things to run under high
 privileges. As far as I know, you can't do that with a DMG package, but
 can do it with a PKG package.
You can do that from inside your application. For example, Xcode has a separate preference pane to download the iOS simulator of various versions, same thing for the documentation. TextMate and GitX has a menu that allow you to install the command line tools for the application.
 I've learned a tremendous amount about PKG packages (the docs are
 difficult), but the one thing that doesn't seem possible is to download
 a component from a remote URL with it except via a Perl or Bash script.
 The PKG flat format supports a way to call a preinstall and postinstall
 Perl or Bash script. The trouble with that technique, however, is that
 if you have a 30MB download that takes awhile, the installer screen sits
 at "Running Package Scripts..." for like 3 minutes (on 2Mbps DSL) and
 this can confuse the consumer into thinking the installer is hung up,
 when it isn't.
Why can't you bundle everything in the PKG package? What's the advantage of first downloading a small binary/package which then downloads the real application?
 The thing I'd like to achieve with D is to have my Bash or Perl script
 call a command line D application that finds the current installer
 window x,y, hides the Cocoa-based window, draws my new Cocoa-based
 window to replace it at the same x,y,w,h as the other one, and then runs
 curl command to download the file, then uses the D application again to
 stop showing my custom window, unhide the installer window, and exit the
 Bash script.
If you really go that route (still don't see why this would be necessary) I guess DerelictCocoa is the way to go [1], or even better use the new Objective-C support that D got in the latest version of DMD [2].
 So, some things I need to learn in D:

 * How to enumerate the currently visible Cocoa windows and their titles
 or internal names, along with their window handle.

 * How to get the x,y of an existing Cocoa window by its window handle.

 * How to hide a Cocoa window by its window handle.

 * How to draw my own Cocoa window at an x,y coordinate.

 * How to destroy my Cocoa window by its window handle.

 * How to unhide a previously hidden Cocoa window by its window handle.
These are not specific for D. You can search for how to do this in Objective-C/Swift and then figure out how to translate the code to D. [1] https://github.com/p0nce/DerelictCocoa/tree/master/examples/window [2] http://dlang.org/spec/objc_interface.html -- /Jacob Carlborg
Nov 29 2015
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-11-29 03:30, Mike McKee wrote:

 Currently nothing like that exists on
 OSX, but does exist on Windows via the Inno Setup and InstallShield
 platforms.
I would like to add that if you want to distribute an application on OS X you should do that according to the standards of the platform, which the users are familiar with. Not how it's done on some other platform. You could also look in to this application [1] that allows you to create PKG packages. [1] http://s.sudre.free.fr/Software/Packages/about.html -- /Jacob Carlborg
Nov 29 2015