How to create a window in browser which has a NSWindow handle? - nswindow

I am making a plugin for safari on mac. I am stuck at how to create a window over browser's window upon which a video can be displayed.
Earlier, we were using Cocoa Event model under which window pointer received in NPWindow in NPP_SetWindow function is null. Then we switched to Carbon Event model and we got pointer to NP_CGContext via window pointer present in NPWindow struct, using which we got pointer to WindowRef and got a pointer to NSWindow as following:
NP_CGContext* npContext = (NP_CGContext*)npWindow->window;
WindowRef window = npContext->window;
NSWindow* browserWindow = [[[NSWindow alloc] initWithWindowRef:window] autorelease];
Our streaming engine accepts the pointer to NSWindow. We don't know how to create a window in our browser space.
So any help regarding the window creation would be appreciated.

Our streaming engine accepts the pointer to NSWindow. We don't know how to create a window in our browser space.
You should not do this, as explained in previous answers.
A streaming engine that requires an NSWindow pointer is very poorly suited to making an NPAPI plugin. You should if at all possible look for something that takes or vends a CALayer, or failing that, which can draw frames into CGContextRef (but this will be much slower in out-of-process plugins).
If you absolutely must use an NSWindow, then you'll need to make a new one in your plugin process that is completely unrelated to the browser's window, and display it somewhere on screen. The user experience will be relatively poor, because it won't move with the window, can end up behind the browser window, etc. This is explicitly discouraged by browser vendors. But if you have no choice but to use an NSWindow, then this is your only option with modern browsers.

Related

How to scroll window contents using Direct2D api?

I would like to scroll window contents in which drawing is performed with Direct2D api through ID2D1RenderTarget.
In GDI I could create a buffer with CreateCompatibleDC and later scroll its contents with ScrollDC, redraw exposed area and BitBlt the buffer to window.
I cannot see any necessary API in Direct2D to perform the same operations. How can I achieve the same functionality without using GetDC (and GDI), and without using own third buffer?
There is no Scroll API in Direct2D. Your best solution to get hardware accelerated scrolling is to use a 2nd buffer. On the ID2D1RenderTarget that you want to scroll, use CreateCompatibleRenderTarget() to create an ID2D1BitmapRenderTarget (it's a good idea to cache this guy) with the same pixel size as ID2D1RenderTarget::GetPixelSize() and with the same resolution as returned from ID2D1RenderTarget::GetDpi(). Then, use ID2D1BitmapRenderTarget::GetBitmap() to get the underlying ID2D1Bitmap. Next, use ID2D1Bitmap::CopyFromRenderTarget() copy the contents with adjustments for the distance you're scrolling. Then copy that bitmap's contents back to the original render target, re-render the uncovered area, and present (via EndDraw).
You can use translation.
MSDN: To translate a 2-D object is to move the object along the x-axis, the y-axis, or both.
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Translation(20, 10));
More details here
http://msdn.microsoft.com/en-us/library/windows/desktop/dd756691(v=vs.85).aspx
In DXGI 1.2 there is a new IDXGISwapChain1::Present1 API call with DXGI_PRESENT_PARAMETERS
parameter. It contains functionality supporting scrolling window contents.

Slow repaint underneath dragged object on X... Can Qt force drag and drop operations to be internal only?

I'm implementing Qt's drag and drop API across Windows and X. When I pick up an object in the app running on X and drag it, it leaves a white ghost trail of itself on the window underneath, as if the window underneath is being slow to repaint where the dragged object was previously obscuring part of itself.
I believe that this is symptomatic of the same problem that Qt has just solved with resizing windows causing flicker in child widgets on X windows - i.e. the dragged object is treated as a separate native window and therefore X handles the clipping from the dragged object to the window underneath. Since X does this in a different way to Qt, we get the ghosting effect.
Has anyone experienced the same problems? One solution that comes to mind is to use the same technique as detailed in the blog article linked above and stop the dragged object being treated as a native window, presumably at the cost of drag and drop being limited to my application only (I have no problem with this). Would anyone know how to force drag and drop operations to be internal only?
EDIT: I'm using QDrag::setPixmap to set the graphical representation of the dragged object - it is important that I retain this in favour of a standard drag cursor as this interface is being used on a touchscreen device and will hence have no visible cursor.
I'm now of the opinion that short of editing and then compiling my own build of Qt (not an option for me), I can't force drag and drop operations to be internal only.
Equally, I can't find any way of getting rid of the ghost trail by tweaking my window manager settings or using a compositing window manager (thanks anyway though #atomice). Using OpenGL as the renderer increases the screen repaint speed slightly, but is not perfect and introduces its own problems (see Starting a Qt drag operation on X11 w/ OpenGL causes screen flicker). I would still be very interested to hear any ideas though.
I have, however, got a workaround for my problem which works on both Windows and X. Here's a simplified version:
void DoDrag()
{
//Prepare the graphical representation of the drag
mDragRepresenter = new QWidget(QApplication::activeWindow());
mDragRepresenter->setAttribute(Qt::WA_TransparentForMouseEvents);
mDragRepresenter->SetPixmap(GenerateDragPixmap());
RepositionDragRepresenter();
mDragRepresenter->show();
QTimer UpdateTimer;
connect(&UpdateTimer, SIGNAL(timeout()), this, SLOT(RepositionDragRepresenter()));
UpdateTimer.start(40);
//Start the drag (modal operation)
Qt::DropAction ResultingAction = Drag->exec(Qt::CopyAction);
UpdateTimer.stop();
delete mDragRepresenter;
}
void RepositionDragRepresenter()
{
mDragRepresenter->move(QApplication::activeWindow()->mapFromGlobal(QCursor::pos()) - mDragRepresenterHotSpot);
}
An X11 window is only created for a drag operation if a QDrag::mimeData()->hasImage() is true. If you modify your code so it doesn't use an image then you will just get a drag cursor instead which won't trigger a repaint of the windows underneath.
You don't specify what kind of object you are dragging or how you are setting up the drag operation. Can you add some code to show that?

Taking a screenshot of browser/tab window in flex

I'm quite new to Flex.
I've looked into taking screenshots in flex and have found many links on google and here on stackoverflow for taking screenshots of components and stuff like this. What I would like to do is take a screenshot of the entire tab in a browser window (or, failing that, the browser window itself or even just the screen).
I'm able to take a screenshot of a viewstack because it implements the IBitmapDrawable interface. But what if I want to take a screenshot of the browser tab as mentioned? Is this possible and, if so, how?
The parent of the viewstack is the application but when trying to pass Application.application to the draw method of the BitmapData class, I get the following error:
Implicit coercion of a value with static type Object to a possibly unrelated type flash.display:IBitmapDrawable.
Thanks in advance.
It's not possible to take screenshots of anything that's outside of your Flex application. However, it should be possible to take a screenshot of your application. Application is a DisplayObject which implements IBitmapDrawable. The reason for your error is, that Application.application is of type Object. So, you should be able to cast your application as IBitmapDrawable and use it to get a screenshot of your application.
// Flex 3.x
var app:IBitmapDrawable = Application.application as IBitmapDrawable;
// in Flex SDK 4.x Application.application is deprecated so use
var app:IBitmapDrawable = FlexGlobals.topLevelApplication as IBitmapDrawable;
Sorry, but it is not possible to take screenshots of the complete browser window or tab. You can also capture what runs inside of Flash Player. This is a security issue.
When dealing with Adobe Air applications, this is different, as you have a stronger connection to native OS functions.
If this helps, please vote for the answer.

Bring a window to the front in Maemo

I've got a Maemo (Qt) app that does some integration with the built-in media player via D-Bus. All the control functionality I need is complete, but I've got a requirement to show my application window (which gets backgrounded when playback starts) instead of the media player when the playback window is closed (it's a stacked window).
It should go like this: user clicks item in my Qt application, which launches the media file in the native media player. User watches media file, exits by clicking the arrow on the playback window. I'd like to somehow catch this event and bring my application to the front instead of showing the media player's main window.
Is it even possible on Maemo? I'm thinking that some low-level X coding might be required.
Answer was painfully obvious, I can catch a state_changed signal from D-Bus- state=0 when the window is closed.
You can also use the raise() method of Qt windows.

Flex-AIR: Make application with NO tab in taskbar?

I have an AIR app about half way done right now. I was informed by the client today that he does not want a tab to show up in his task bar. I already have this in place for new windows by making them lightweight. I do not know how to make the main window lightweight though. If there is not a way, is there a work around, like not not having a main window and just opening lightweight windows, don't know how that could be done either though? Anyone know how to do this?
Thanks!
Check this doc out. -- Yes, you can do this. In short, you have to hide the initial window - then display your application in a lightweight window.
Also - do note: On a Mac - the behavior is different. By convention, a window is not shown in the 'task bar' when it is displayed. When it is minimized it is in the bar. To hide the application when minimized on a Mac - you have to make the window 'invisible' instead of minimizing it. The doc mentioned above gives further details.
The key part of the doc for your case:
On the Windows operating system,
windows created with the types utility
or lightweight do not appear on the
taskbar. Invisible windows do not
appear on the taskbar, either.
Because the initial window is
necessarily of type, normal, in order
to create an application without any
windows appearing in the taskbar, you
must either close the inital window or
leave it invisible.
To close all
windows in your application without
terminating the application, set the
autoExit property of the
NativeApplication object to false
before closing the last window. To
simply prevent the intial window from
ever becoming visible, add
false to the
element of the
application descriptor file (and do
not set the visible property to true
or call the activate() method of the
window).
In new windows opened by the
application, set the type property of
the NativeWindowInitOption object
passed to the window constructor to
NativeWindowType.UTILITY or
NativeWindowType.LIGHTWEIGHT.

Resources