[Interest] Using Qt as backend for plugin to be loaded on a host software

Nuno Santos nunosantos at imaginando.pt
Sun Sep 20 23:04:48 CEST 2015


Hi,

I have made successfully managed to embed a QML window into a Carbon window. I would like to share my solution and discuss it further with any interested in the subject.

First I get the Carbon window ref and get the content HIView. The content view tells me the size of the Carbon window given by the host. I then create a HICocoaView and add it as child of content view. I also set the cocoa view frame to be the same as content frame. I terminate returning a new QWindow. 

QWindow* Editor::fromWindowRef(void *ptr)
{
    HIRect frame;
    HIViewRef content;

    WindowRef w= (WindowRef) ptr;

    HIViewFindByID(HIViewGetRoot(w), kHIViewWindowContentID, &content);
    HIViewGetFrame(content, &frame);
    HICocoaViewCreate(0, 0, &hiCocoaView);
    HIViewSetFrame(hiCocoaView, &frame);
    HIViewAddSubview(content, hiCocoaView);

    return new QWindow;
}

After the QWindow is created I get it’s winId and pass it to the next function which casts the WId to a NSView and sets it into cocoa wrapper view:

void IVstEditor::wrapIntoHostWindow(WId id)
{
    HICocoaViewSetView(hiCocoaView, (NSView*)id);
}

Now the QML window is inside the carbon window and the GUI is responding to interaction! :)

From my testings, it was not possible to have a window open by trying to create an NSWindow and initialise it with the carbon window ref. It would never show up. Also, trying to initialise QWindow with a pointer to NSWindow content NSView would always crash. However, if queried, the HIView returned has visible and with the correct frame size.

Nuno Santos
Founder / CEO / CTO
www.imaginando.pt
+351 91 621 69 62

> On 16 Sep 2015, at 20:06, Nuno Santos <nunosantos at imaginando.pt> wrote:
> 
> Hi,
> 
> After spending the whole day around Carbon and HIToolbox I’m now sure that the WindowRef provided is a for a Carbon window. However I’m not been able to add a single colored NSView to the windows provided by the host. This what I have been trying to do. Is there anyone with experience in Carbon here? Can you see something terribly wrong? The window appears completely white, always!
> 
> WindowRef w= (WindowRef) ptr;
> 
> NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
> [view setWantsLayer:YES];
> view.layer.backgroundColor = [[NSColor yellowColor] CGColor];
> NSLog(@"view frame - %f %f %f %f", view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
> 
> HIViewRef content;
> HIViewFindByID(HIViewGetRoot(w), kHIViewWindowContentID, &content);
> 
> HIRect frame;
> HIViewGetFrame(content, &frame);
> NSLog(@"content frame - %f %f %f %f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
> 
> HIViewRef hiCocoaView;
> HICocoaViewCreate(view, 0, &hiCocoaView);
> frame.origin.x=0;
> frame.origin.y=0;
> frame.size.width=640;
> frame.size.height=480;
> HIViewSetFrame(hiCocoaView, &frame);
> HIViewGetFrame(hiCocoaView, &frame);
> NSLog(@"cocoa view frame - %f %f %f %f", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
> 
> HICocoaViewSetView(hiCocoaView, view);
> 
> HIViewSetVisible(hiCocoaView, true);
> HIViewSetNeedsDisplay(hiCocoaView, true);
> 
> HIViewAddSubview(content, hiCocoaView);
> HIViewSetNeedsDisplay(content, true);
> HIViewSetVisible(content, true);
> 
> 2015-09-16 18:19:30.387 Live[93099:1193953] view frame - 0.000000 0.000000 100.000000 100.000000
> 2015-09-16 18:19:30.387 Live[93099:1193953] content frame - 0.000000 16.000000 1024.000000 768.000000
> 2015-09-16 18:19:30.387 Live[93099:1193953] cocoa view frame - 0.000000 0.000000 640.000000 480.000000
> 
> Nuno Santos
> Founder / CEO / CTO
> www.imaginando.pt <http://www.imaginando.pt/>
> +351 91 621 69 62
> 
>> On 16 Sep 2015, at 14:36, Nuno Santos <nunosantos at imaginando.pt <mailto:nunosantos at imaginando.pt>> wrote:
>> 
>> Hi.
>> 
>> I’m developing a plugin to be loaded by a music software host (VST). There are some lighter alternatives to provide graphics, network and other kinds of useful resources but I want to use Qt. I simply Love Qt!
>> 
>> When the plugin is open by the host, it provides a window ref to the plugin. On Window it is a HWND handle, on Mac it is supposedly a WindowRef.
>> 
>> I have a working prototype for Windows. I don’t think it is all correct but its working. When the plugin is first started I check for the existence of a QApplication and start one if not.
>> 
>> Then I create the main controller for my plugin and the QQuickView to draw on the window. To create the QQuickView i’m first creating a QWindow with the ptr to HWND handle as parent:
>> 
>> window = QWindow::fromWinId((WId)ptr);
>> 
>> view = new QQuickView(window);
>> view->setSource(QUrl("qrc:/qml/vstmain.qml"));
>> view->rootContext()->setContextProperty("controller", _controller);
>> view->show();
>> 
>> This is actually working quite well on Windows. The same strategy however, doesn’t work on a Mac. When I try to create a QWindow::fromWinId the result is a crash with the following stack trace:
>> 
>> 2015-09-16 14:26:18.526 Live[91339:1091079] -[NSHIObject setPostsFrameChangedNotifications:]: unrecognized selector sent to instance 0x19806da0
>> 
>> - The first question is: what is QWindow::fromWinId is expecting to be able to create a window? An NSView?
>> 
>> - The second question is: the stack trace says that NSHIObject didn’t recognized the selector setPostsFrameChangedNotifications. What is a NSHIObject? I can only find references to HIObject from the HIToolbox and that belongs to the Carbon frame work. So far I haven’t been able to call Carbon methods inside my Qt environment even referencing -framework Carbon
>> 
>> - Third question: On window I have an issue with the QApplication args and argv. On debug, there is an ASSERT that says that origArgc is different from the actual argc/argv. On release mode it crashes. Why does QApplication needs to receive the exact same arguments as the initial app? 
>> 
>> - Fourth question: how should I keep my run loop running without depending on the host? On Windows I have created a windows thread to call qApp->exec(). Although a warning that exec should be called on main thread it WORKS! How safe is this? Is there any other recommended option? What about Mac OS X?
>> 
>> I have been google a lot specially about the NSHIObject and I can’t find an answer, not even a simple lead. The closest I have is vstgui, a GUI framework for VST plugins that has open source code and support for Carbon and Cocoa backends but the NSHIObject is intriguing me because I can’t find any explicit reference on how to deal with it.
>> 
>> Any thoughts would be high appreciated.
>> 
>> Thanks in advance,
>> 
>> With my best regards,
>> 
>> Nuno
>> _______________________________________________
>> Interest mailing list
>> Interest at qt-project.org <mailto:Interest at qt-project.org>
>> http://lists.qt-project.org/mailman/listinfo/interest
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20150920/3d1c45ee/attachment.html>


More information about the Interest mailing list