1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim:expandtab:shiftwidth=4:tabstop=4:
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "mozilla/ArrayUtils.h"
9 #include "mozilla/MiscEvents.h"
10 #include "mozilla/MouseEvents.h"
11 #include "mozilla/TextEvents.h"
12 #include "mozilla/TouchEvents.h"
14 #include <QGuiApplication>
15 #include <QtGui/QCursor>
17 #include <QMouseEvent>
18 #include <QWheelEvent>
19 #include <QResizeEvent>
20 #include <QPaintEngine>
24 #include <QtCore/QDebug>
25 #include <QtCore/QEvent>
26 #include <QtCore/QVariant>
31 #include <X11/Xutil.h>
32 #include "gfxXlibSurface.h"
35 #include "nsXULAppAPI.h"
40 #include "mozqwidget.h"
42 #include "nsIdleService.h"
43 #include "nsRenderingContext.h"
44 #include "nsIRollupListener.h"
45 #include "nsWidgetsCID.h"
46 #include "nsQtKeyUtils.h"
47 #include "mozilla/Services.h"
48 #include "mozilla/Preferences.h"
49 #include "mozilla/Likely.h"
50 #include "mozilla/layers/LayersTypes.h"
51 #include "nsIWidgetListener.h"
52 #include "ClientLayerManager.h"
53 #include "BasicLayers.h"
55 #include "nsIStringBundle.h"
56 #include "nsGfxCIID.h"
58 #include "imgIContainer.h"
59 #include "nsGfxCIID.h"
60 #include "nsIInterfaceRequestorUtils.h"
61 #include "nsAutoPtr.h"
63 #include "gfxQtPlatform.h"
65 #include "nsIDOMWheelEvent.h"
67 #include "GLContext.h"
70 #include "keysym2ucs.h"
74 #include "GLContextProvider.h"
76 using namespace mozilla
;
77 using namespace mozilla::gl
;
78 using namespace mozilla::widget
;
79 using namespace mozilla::gfx
;
80 using namespace mozilla::layers
;
81 using mozilla::gl::GLContext
;
83 #define kWindowPositionSlop 20
86 static const int WHEEL_DELTA
= 120;
87 static bool gGlobalsInitialized
= false;
88 static bool sAltGrModifier
= false;
90 static void find_first_visible_parent(QWindow
* aItem
, QWindow
*& aVisibleItem
);
91 static bool is_mouse_in_window (MozQWidget
* aWindow
, double aMouseX
, double aMouseY
);
95 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
, (void *)this));
103 mActivatePending
= false;
104 mWindowType
= eWindowType_child
;
105 mSizeState
= nsSizeMode_Normal
;
106 mLastSizeMode
= nsSizeMode_Normal
;
107 mQCursor
= Qt::ArrowCursor
;
108 mNeedsResize
= false;
110 mListenForResizes
= false;
112 mTimerStarted
= false;
113 mMoveEvent
.needDispatch
= false;
115 if (!gGlobalsInitialized
) {
116 gfxPlatform::GetPlatform();
117 gGlobalsInitialized
= true;
120 memset(mKeyDownFlags
, 0, sizeof(mKeyDownFlags
));
122 mIsTransparent
= false;
124 mCursor
= eCursor_standard
;
127 nsWindow::~nsWindow()
129 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
, (void *)this));
135 nsWindow::Create(nsIWidget
*aParent
,
136 nsNativeWidget aNativeParent
,
137 const nsIntRect
&aRect
,
138 nsDeviceContext
*aContext
,
139 nsWidgetInitData
*aInitData
)
141 // only set the base parent if we're not going to be a dialog or a
143 nsIWidget
*baseParent
= aParent
;
145 // initialize all the common bits of this class
146 BaseCreate(baseParent
, aRect
, aContext
, aInitData
);
150 // and do our common creation
151 mParent
= (nsWindow
*)aParent
;
156 // find native parent
157 MozQWidget
*parent
= nullptr;
159 if (aParent
!= nullptr) {
160 parent
= static_cast<MozQWidget
*>(aParent
->GetNativeData(NS_NATIVE_WIDGET
));
161 } else if (aNativeParent
!= nullptr) {
162 parent
= static_cast<MozQWidget
*>(aNativeParent
);
163 if (parent
&& mParent
== nullptr) {
164 mParent
= parent
->getReceiver();
168 LOG(("Create: nsWindow [%p] mWidget:[%p] parent:[%p], natPar:[%p] mParent:%p\n", (void *)this, (void*)mWidget
, parent
, aNativeParent
, mParent
));
170 // ok, create our QGraphicsWidget
171 mWidget
= createQWidget(parent
, aInitData
);
174 return NS_ERROR_OUT_OF_MEMORY
;
178 // resize so that everything is set to the right dimensions
179 Resize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
, false);
181 // check if we should listen for resizes
182 mListenForResizes
= (aNativeParent
||
183 (aInitData
&& aInitData
->mListenForResizes
));
189 nsWindow::createQWidget(MozQWidget
* parent
,
190 nsWidgetInitData
* aInitData
)
192 const char *windowName
= nullptr;
193 Qt::WindowFlags flags
= Qt::Widget
;
195 // ok, create our windows
196 switch (mWindowType
) {
197 case eWindowType_dialog
:
198 windowName
= "topLevelDialog";
201 case eWindowType_popup
:
202 windowName
= "topLevelPopup";
205 case eWindowType_toplevel
:
206 windowName
= "topLevelWindow";
209 case eWindowType_invisible
:
210 windowName
= "topLevelInvisible";
212 case eWindowType_child
:
213 case eWindowType_plugin
:
215 windowName
= "paintArea";
219 MozQWidget
* widget
= new MozQWidget(this, parent
);
224 widget
->setObjectName(QString(windowName
));
225 if (mWindowType
== eWindowType_invisible
) {
226 #if (QT_VERSION >= QT_VERSION_CHECK(5, 1, 0))
227 widget
->setVisibility(QWindow::Hidden
);
232 if (mWindowType
== eWindowType_dialog
) {
233 widget
->setModality(Qt::WindowModal
);
238 // create a QGraphicsView if this is a new toplevel window
239 LOG(("nsWindow::%s [%p] Created Window: %s, widget:%p, par:%p\n", __FUNCTION__
, (void *)this, windowName
, widget
, parent
));
245 nsWindow::Destroy(void)
247 if (mIsDestroyed
|| !mWidget
) {
251 LOG(("nsWindow::Destroy [%p]\n", (void *)this));
254 /** Need to clean our LayerManager up while still alive */
256 mLayerManager
->Destroy();
258 mLayerManager
= nullptr;
260 // It is safe to call DestroyeCompositor several times (here and
261 // in the parent class) since it will take effect only once.
262 // The reason we call it here is because on gtk platforms we need
263 // to destroy the compositor before we destroy the gdk window (which
264 // destroys the the gl context attached to it).
267 ClearCachedResources();
269 nsIRollupListener
* rollupListener
= nsBaseWidget::GetActiveRollupListener();
270 if (rollupListener
) {
271 nsCOMPtr
<nsIWidget
> rollupWidget
= rollupListener
->GetRollupWidget();
272 if (static_cast<nsIWidget
*>(this) == rollupWidget
) {
273 rollupListener
->Rollup(0, nullptr, nullptr);
279 // walk the list of children and call destroy on them. Have to be
280 // careful, though -- calling destroy on a kid may actually remove
281 // it from our child list, losing its sibling links.
282 for (nsIWidget
* kid
= mFirstChild
; kid
; ) {
283 nsIWidget
* next
= kid
->GetNextSibling();
288 // Destroy thebes surface now. Badness can happen if we destroy
289 // the surface after its X Window.
291 mWidget
->dropReceiver();
293 // Call deleteLater instead of delete; Qt still needs the object
294 // to be valid even after sending it a Close event. We could
295 // also set WA_DeleteOnClose, but this gives us more control.
296 mWidget
->deleteLater();
306 nsWindow::Show(bool aState
)
308 LOG(("nsWindow::Show [%p] state %d\n", (void *)this, aState
));
309 if (aState
== mIsShown
) {
313 // Clear our cached resources when the window is hidden.
314 if (mIsShown
&& !aState
) {
315 ClearCachedResources();
320 if ((aState
&& !AreBoundsSane()) || !mWidget
) {
321 LOG(("\tbounds are insane or window hasn't been created yet\n"));
328 NativeResize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
,
330 } else if (mNeedsResize
) {
331 NativeResize(mBounds
.width
, mBounds
.height
, false);
335 // If someone is hiding this widget, clear any needing show flag.
345 nsWindow::IsVisible() const
351 nsWindow::ConstrainPosition(bool aAllowSlop
, int32_t *aX
, int32_t *aY
)
354 return NS_ERROR_FAILURE
;
357 int32_t screenWidth
= qApp
->primaryScreen()->size().width();
358 int32_t screenHeight
= qApp
->primaryScreen()->size().height();
361 if (*aX
< (kWindowPositionSlop
- mBounds
.width
))
362 *aX
= kWindowPositionSlop
- mBounds
.width
;
363 if (*aX
> (screenWidth
- kWindowPositionSlop
))
364 *aX
= screenWidth
- kWindowPositionSlop
;
365 if (*aY
< (kWindowPositionSlop
- mBounds
.height
))
366 *aY
= kWindowPositionSlop
- mBounds
.height
;
367 if (*aY
> (screenHeight
- kWindowPositionSlop
))
368 *aY
= screenHeight
- kWindowPositionSlop
;
372 if (*aX
> (screenWidth
- mBounds
.width
))
373 *aX
= screenWidth
- mBounds
.width
;
376 if (*aY
> (screenHeight
- mBounds
.height
))
377 *aY
= screenHeight
- mBounds
.height
;
384 nsWindow::Move(double aX
, double aY
)
386 LOG(("nsWindow::Move [%p] %f %f\n", (void *)this,
389 int32_t x
= NSToIntRound(aX
);
390 int32_t y
= NSToIntRound(aY
);
393 SetSizeMode(nsSizeMode_Normal
);
396 if (x
== mBounds
.x
&& y
== mBounds
.y
) {
405 mWidget
->setPosition(x
, y
);
408 // the position of the widget is set relative to the parent
409 // so we map the coordinates accordingly
410 pos
= mWidget
->mapToGlobal(pos
);
411 mWidget
->setPosition(pos
);
417 NotifyRollupGeometryChange();
422 nsWindow::Resize(double aWidth
, double aHeight
, bool aRepaint
)
424 mBounds
.width
= NSToIntRound(aWidth
);
425 mBounds
.height
= NSToIntRound(aHeight
);
431 if (AreBoundsSane()) {
432 if (mIsTopLevel
|| mNeedsShow
)
433 NativeResize(mBounds
.x
, mBounds
.y
,
434 mBounds
.width
, mBounds
.height
, aRepaint
);
436 NativeResize(mBounds
.width
, mBounds
.height
, aRepaint
);
438 // Does it need to be shown because it was previously insane?
444 // If someone has set this so that the needs show flag is false
445 // and it needs to be hidden, update the flag and hide the
446 // window. This flag will be cleared the next time someone
447 // hides the window or shows it. It also prevents us from
448 // calling NativeShow(false) excessively on the window which
449 // causes unneeded X traffic.
456 else if (AreBoundsSane() && mListenForResizes
) {
457 // For widgets that we listen for resizes for (widgets created
458 // with native parents) we apparently _always_ have to resize. I
459 // dunno why, but apparently we're lame like that.
460 NativeResize(mBounds
.width
, mBounds
.height
, aRepaint
);
466 // synthesize a resize event if this isn't a toplevel
467 if (mIsTopLevel
|| mListenForResizes
) {
468 nsEventStatus status
;
469 DispatchResizeEvent(mBounds
, status
);
472 NotifyRollupGeometryChange();
477 nsWindow::Resize(double aX
, double aY
, double aWidth
, double aHeight
,
480 mBounds
.x
= NSToIntRound(aX
);
481 mBounds
.y
= NSToIntRound(aY
);
482 mBounds
.width
= NSToIntRound(aWidth
);
483 mBounds
.height
= NSToIntRound(aHeight
);
491 // Has this widget been set to visible?
493 // Are the bounds sane?
494 if (AreBoundsSane()) {
495 // Yep? Resize the window
496 NativeResize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
,
498 // Does it need to be shown because it was previously insane?
503 // If someone has set this so that the needs show flag is false
504 // and it needs to be hidden, update the flag and hide the
505 // window. This flag will be cleared the next time someone
506 // hides the window or shows it. It also prevents us from
507 // calling NativeShow(false) excessively on the window which
508 // causes unneeded X traffic.
515 // If the widget hasn't been shown, mark the widget as needing to be
516 // resized before it is shown
517 else if (AreBoundsSane() && mListenForResizes
) {
518 // For widgets that we listen for resizes for (widgets created
519 // with native parents) we apparently _always_ have to resize. I
520 // dunno why, but apparently we're lame like that.
521 NativeResize(mBounds
.x
, mBounds
.y
, mBounds
.width
, mBounds
.height
,
529 if (mIsTopLevel
|| mListenForResizes
) {
530 // synthesize a resize event
531 nsEventStatus status
;
532 DispatchResizeEvent(mBounds
, status
);
536 mWidget
->renderLater();
539 NotifyRollupGeometryChange();
544 nsWindow::Enable(bool aState
)
552 nsWindow::IsEnabled() const
558 nsWindow::SetFocus(bool aRaise
)
560 // Make sure that our owning widget has focus. If it doesn't try to
561 // grab it. Note that we don't set our focus flag in this case.
562 LOGFOCUS((" SetFocus [%p]\n", (void *)this));
565 return NS_ERROR_FAILURE
;
568 if (mWidget
->focusObject()) {
572 // Because QGraphicsItem cannot get the focus if they are
573 // invisible, we look up the chain, for the lowest visible
574 // parent and focus that one
575 QWindow
* realFocusItem
= nullptr;
576 find_first_visible_parent(mWidget
, realFocusItem
);
578 if (!realFocusItem
|| realFocusItem
->focusObject()) {
582 if (aRaise
&& mWidget
) {
583 // the raising has to happen on the view widget
587 // XXXndeakin why is this here? It should dispatch only when the OS
589 DispatchActivateEvent();
595 nsWindow::ConfigureChildren(const nsTArray
<nsIWidget::Configuration
>& aConfigurations
)
597 for (uint32_t i
= 0; i
< aConfigurations
.Length(); ++i
) {
598 const Configuration
& configuration
= aConfigurations
[i
];
600 nsWindow
* w
= static_cast<nsWindow
*>(configuration
.mChild
);
601 NS_ASSERTION(w
->GetParent() == this,
602 "Configured widget is not a child");
604 if (w
->mBounds
.Size() != configuration
.mBounds
.Size()) {
605 w
->Resize(configuration
.mBounds
.x
, configuration
.mBounds
.y
,
606 configuration
.mBounds
.width
, configuration
.mBounds
.height
,
608 } else if (w
->mBounds
.TopLeft() != configuration
.mBounds
.TopLeft()) {
609 w
->Move(configuration
.mBounds
.x
, configuration
.mBounds
.y
);
616 nsWindow::Invalidate(const nsIntRect
&aRect
)
618 LOGDRAW(("Invalidate (rect) [%p,%p]: %d %d %d %d\n", (void *)this,
619 (void*)mWidget
,aRect
.x
, aRect
.y
, aRect
.width
, aRect
.height
));
625 mWidget
->renderLater();
631 nsWindow::WidgetToScreenOffset()
633 NS_ENSURE_TRUE(mWidget
, nsIntPoint(0,0));
636 origin
= mWidget
->mapToGlobal(origin
);
638 return nsIntPoint(origin
.x(), origin
.y());
642 nsWindow::GetNativeData(uint32_t aDataType
)
645 case NS_NATIVE_WINDOW
:
646 case NS_NATIVE_WIDGET
: {
649 case NS_NATIVE_SHAREABLE_WINDOW
: {
650 return mWidget
? (void*)mWidget
->winId() : nullptr;
652 case NS_NATIVE_DISPLAY
: {
654 return gfxQtPlatform::GetXDisplay(mWidget
);
658 case NS_NATIVE_PLUGIN_PORT
:
659 case NS_NATIVE_GRAPHIC
:
660 case NS_NATIVE_SHELLWIDGET
: {
664 NS_WARNING("nsWindow::GetNativeData called with bad value");
667 LOG(("nsWindow::%s [%p] aDataType:%i\n", __FUNCTION__
, (void *)this, aDataType
));
672 nsWindow::DispatchEvent(WidgetGUIEvent
* aEvent
, nsEventStatus
& aStatus
)
675 debug_DumpEvent(stdout
, aEvent
->widget
, aEvent
,
676 nsAutoCString("something"), 0);
679 aStatus
= nsEventStatus_eIgnore
;
681 // send it to the standard callback
682 if (mWidgetListener
) {
683 aStatus
= mWidgetListener
->HandleEvent(aEvent
, mUseAttachedEvents
);
690 nsWindow::SetInputContext(const InputContext
& aContext
,
691 const InputContextAction
& aAction
)
693 NS_ENSURE_TRUE_VOID(mWidget
);
695 // SetSoftwareKeyboardState uses mInputContext,
696 // so, before calling that, record aContext in mInputContext.
697 mInputContext
= aContext
;
699 switch (mInputContext
.mIMEState
.mEnabled
) {
700 case IMEState::ENABLED
:
701 case IMEState::PASSWORD
:
702 case IMEState::PLUGIN
:
703 SetSoftwareKeyboardState(true, aAction
);
706 SetSoftwareKeyboardState(false, aAction
);
711 NS_IMETHODIMP_(InputContext
)
712 nsWindow::GetInputContext()
714 mInputContext
.mIMEState
.mOpen
= IMEState::OPEN_STATE_NOT_SUPPORTED
;
715 // Our qt widget looks like using only one context per process.
716 // However, it's better to set the context's pointer.
717 mInputContext
.mNativeIMEContext
= qApp
->inputMethod();
719 return mInputContext
;
723 nsWindow::ReparentNativeWidget(nsIWidget
*aNewParent
)
725 NS_PRECONDITION(aNewParent
, "");
727 MozQWidget
* newParent
= static_cast<MozQWidget
*>(aNewParent
->GetNativeData(NS_NATIVE_WINDOW
));
728 NS_ASSERTION(newParent
, "Parent widget has a null native window handle");
730 mWidget
->setParent(newParent
);
736 nsWindow::MakeFullScreen(bool aFullScreen
)
738 NS_ENSURE_TRUE(mWidget
, NS_ERROR_FAILURE
);
741 if (mSizeMode
!= nsSizeMode_Fullscreen
) {
742 mLastSizeMode
= mSizeMode
;
745 mSizeMode
= nsSizeMode_Fullscreen
;
746 mWidget
->showFullScreen();
749 mSizeMode
= mLastSizeMode
;
752 case nsSizeMode_Maximized
:
753 mWidget
->showMaximized();
755 case nsSizeMode_Minimized
:
756 mWidget
->showMinimized();
758 case nsSizeMode_Normal
:
759 mWidget
->showNormal();
762 mWidget
->showNormal();
767 NS_ASSERTION(mLastSizeMode
!= nsSizeMode_Fullscreen
,
768 "mLastSizeMode should never be fullscreen");
769 return nsBaseWidget::MakeFullScreen(aFullScreen
);
773 nsWindow::GetLayerManager(PLayerTransactionChild
* aShadowManager
,
774 LayersBackend aBackendHint
,
775 LayerManagerPersistence aPersistence
,
776 bool* aAllowRetaining
)
778 if (!mLayerManager
&& eTransparencyTransparent
== GetTransparencyMode()) {
779 mLayerManager
= CreateBasicLayerManager();
782 return nsBaseWidget::GetLayerManager(aShadowManager
, aBackendHint
,
783 aPersistence
, aAllowRetaining
);
787 nsWindow::UserActivity()
790 mIdleService
= do_GetService("@mozilla.org/widget/idleservice;1");
794 mIdleService
->ResetIdleTimeOut(0);
799 nsWindow::GetGLFrameBufferFormat()
802 mLayerManager
->GetBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL
) {
805 return LOCAL_GL_NONE
;
808 TemporaryRef
<DrawTarget
>
809 nsWindow::StartRemoteDrawing()
816 Display
* dpy
= gfxQtPlatform::GetXDisplay(mWidget
);
817 Screen
* screen
= DefaultScreenOfDisplay(dpy
);
818 Visual
* defaultVisual
= DefaultVisualOfScreen(screen
);
819 gfxASurface
* surf
= new gfxXlibSurface(dpy
, mWidget
->winId(), defaultVisual
,
820 gfxIntSize(mWidget
->width(),
823 IntSize
size(surf
->GetSize().width
, surf
->GetSize().height
);
824 if (size
.width
<= 0 || size
.height
<= 0) {
828 return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf
, size
);
835 nsWindow::SetCursor(nsCursor aCursor
)
837 if (mCursor
== aCursor
&& !mUpdateCursor
) {
840 mUpdateCursor
= false;
843 mWidget
->SetCursor(mCursor
);
849 nsWindow::SetTitle(const nsAString
& aTitle
)
851 QString
qStr(QString::fromUtf16((const ushort
*)aTitle
.BeginReading(), aTitle
.Length()));
853 mWidget
->setTitle(qStr
);
863 LOGDRAW(("nsWindow::%s [%p]\n", __FUNCTION__
, (void *)this));
864 nsIWidgetListener
* listener
=
865 mAttachedWidgetListener
? mAttachedWidgetListener
: mWidgetListener
;
870 listener
->WillPaintWindow(this);
872 switch (GetLayerManager()->GetBackendType()) {
873 case mozilla::layers::LayersBackend::LAYERS_CLIENT
: {
874 nsIntRegion
region(nsIntRect(0, 0, mWidget
->width(), mWidget
->height()));
875 listener
->PaintWindow(this, region
);
879 NS_ERROR("Invalid layer manager");
882 listener
->DidPaintWindow();
886 nsWindow::moveEvent(QMoveEvent
* aEvent
)
888 LOG(("configure event [%p] %d %d\n", (void *)this,
889 aEvent
->pos().x(), aEvent
->pos().y()));
892 if (!mWidget
|| !mWidgetListener
)
893 return nsEventStatus_eIgnore
;
895 if ((mBounds
.x
== aEvent
->pos().x() &&
896 mBounds
.y
== aEvent
->pos().y()))
898 return nsEventStatus_eIgnore
;
901 NotifyWindowMoved(aEvent
->pos().x(), aEvent
->pos().y());
902 return nsEventStatus_eConsumeNoDefault
;
906 nsWindow::resizeEvent(QResizeEvent
* aEvent
)
910 // Generate XPFE resize event
913 rect
.width
= aEvent
->size().width();
914 rect
.height
= aEvent
->size().height();
916 mBounds
.width
= rect
.width
;
917 mBounds
.height
= rect
.height
;
919 nsEventStatus status
;
920 DispatchResizeEvent(rect
, status
);
925 nsWindow::mouseMoveEvent(QMouseEvent
* aEvent
)
929 mMoveEvent
.pos
= aEvent
->pos();
930 mMoveEvent
.modifiers
= aEvent
->modifiers();
931 mMoveEvent
.needDispatch
= true;
932 DispatchMotionToMainThread();
934 return nsEventStatus_eIgnore
;
938 InitMouseEvent(WidgetMouseEvent
& aMouseEvent
, QMouseEvent
* aEvent
,
941 aMouseEvent
.refPoint
.x
= nscoord(aEvent
->pos().x());
942 aMouseEvent
.refPoint
.y
= nscoord(aEvent
->pos().y());
944 aMouseEvent
.InitBasicModifiers(aEvent
->modifiers() & Qt::ControlModifier
,
945 aEvent
->modifiers() & Qt::AltModifier
,
946 aEvent
->modifiers() & Qt::ShiftModifier
,
947 aEvent
->modifiers() & Qt::MetaModifier
);
948 aMouseEvent
.clickCount
= aClickCount
;
950 switch (aEvent
->button()) {
952 aMouseEvent
.button
= WidgetMouseEvent::eLeftButton
;
954 case Qt::RightButton
:
955 aMouseEvent
.button
= WidgetMouseEvent::eRightButton
;
957 case Qt::MiddleButton
:
958 aMouseEvent
.button
= WidgetMouseEvent::eMiddleButton
;
966 IsAcceptedButton(Qt::MouseButton button
)
970 case Qt::RightButton
:
971 case Qt::MiddleButton
:
979 nsWindow::mousePressEvent(QMouseEvent
* aEvent
)
981 // The user has done something.
984 QPoint pos
= aEvent
->pos();
986 // we check against the widgets geometry, so use parent coordinates
989 pos
= mWidget
->mapToGlobal(pos
);
991 if (CheckForRollup(pos
.x(), pos
.y(), false))
992 return nsEventStatus_eIgnore
;
994 if (!IsAcceptedButton(aEvent
->button())) {
995 if (aEvent
->button() == Qt::BackButton
)
996 return DispatchCommandEvent(nsGkAtoms::Back
);
997 if (aEvent
->button() == Qt::ForwardButton
)
998 return DispatchCommandEvent(nsGkAtoms::Forward
);
999 return nsEventStatus_eIgnore
;
1002 WidgetMouseEvent
event(true, NS_MOUSE_BUTTON_DOWN
, this,
1003 WidgetMouseEvent::eReal
);
1004 InitMouseEvent(event
, aEvent
, 1);
1005 nsEventStatus status
= DispatchEvent(&event
);
1007 // Right click on linux should also pop up a context menu.
1008 if (event
.button
== WidgetMouseEvent::eRightButton
&&
1009 MOZ_LIKELY(!mIsDestroyed
)) {
1010 WidgetMouseEvent
contextMenuEvent(true, NS_CONTEXTMENU
, this,
1011 WidgetMouseEvent::eReal
);
1012 InitMouseEvent(contextMenuEvent
, aEvent
, 1);
1013 DispatchEvent(&contextMenuEvent
, status
);
1020 nsWindow::mouseReleaseEvent(QMouseEvent
* aEvent
)
1022 // The user has done something.
1025 if (!IsAcceptedButton(aEvent
->button()))
1026 return nsEventStatus_eIgnore
;
1028 WidgetMouseEvent
event(true, NS_MOUSE_BUTTON_UP
, this,
1029 WidgetMouseEvent::eReal
);
1030 InitMouseEvent(event
, aEvent
, 1);
1031 return DispatchEvent(&event
);
1035 nsWindow::mouseDoubleClickEvent(QMouseEvent
* aEvent
)
1037 // The user has done something.
1040 if (!IsAcceptedButton(aEvent
->button()))
1041 return nsEventStatus_eIgnore
;
1043 WidgetMouseEvent
event(true, NS_MOUSE_DOUBLECLICK
, this,
1044 WidgetMouseEvent::eReal
);
1045 InitMouseEvent(event
, aEvent
, 2);
1046 return DispatchEvent(&event
);
1050 nsWindow::focusInEvent(QFocusEvent
* aEvent
)
1052 LOGFOCUS(("OnFocusInEvent [%p]\n", (void *)this));
1055 return nsEventStatus_eIgnore
;
1058 DispatchActivateEventOnTopLevelWindow();
1060 LOGFOCUS(("Events sent from focus in event [%p]\n", (void *)this));
1061 return nsEventStatus_eIgnore
;
1065 nsWindow::focusOutEvent(QFocusEvent
* aEvent
)
1067 LOGFOCUS(("OnFocusOutEvent [%p]\n", (void *)this));
1070 return nsEventStatus_eIgnore
;
1073 DispatchDeactivateEventOnTopLevelWindow();
1075 LOGFOCUS(("Done with container focus out [%p]\n", (void *)this));
1076 return nsEventStatus_eIgnore
;
1080 IsContextMenuKeyEvent(const QKeyEvent
* aQEvent
)
1082 if (aQEvent
->modifiers() & (Qt::ControlModifier
|
1084 Qt::MetaModifier
)) {
1088 bool isShift
= aQEvent
->modifiers() & Qt::ShiftModifier
;
1089 uint32_t keyCode
= QtKeyCodeToDOMKeyCode(aQEvent
->key());
1090 return (keyCode
== NS_VK_F10
&& isShift
) ||
1091 (keyCode
== NS_VK_CONTEXT_MENU
&& !isShift
);
1095 InitKeyEvent(WidgetKeyboardEvent
& aEvent
, QKeyEvent
* aQEvent
)
1097 aEvent
.InitBasicModifiers(aQEvent
->modifiers() & Qt::ControlModifier
,
1098 aQEvent
->modifiers() & Qt::AltModifier
,
1099 aQEvent
->modifiers() & Qt::ShiftModifier
,
1100 aQEvent
->modifiers() & Qt::MetaModifier
);
1103 (aEvent
.message
== NS_KEY_DOWN
|| aEvent
.message
== NS_KEY_PRESS
) &&
1104 aQEvent
->isAutoRepeat();
1107 if (sAltGrModifier
) {
1108 aEvent
.modifiers
|= (MODIFIER_CONTROL
| MODIFIER_ALT
);
1111 if (aQEvent
->text().length() && aQEvent
->text()[0].isPrint()) {
1112 aEvent
.charCode
= (int32_t) aQEvent
->text()[0].unicode();
1114 aEvent
.mKeyNameIndex
= KEY_NAME_INDEX_PrintableKey
;
1116 aEvent
.charCode
= 0;
1117 aEvent
.keyCode
= QtKeyCodeToDOMKeyCode(aQEvent
->key());
1118 aEvent
.mKeyNameIndex
= QtKeyCodeToDOMKeyNameIndex(aQEvent
->key());
1121 aEvent
.mCodeNameIndex
= ScanCodeToDOMCodeNameIndex(aQEvent
->nativeScanCode());
1123 // The transformations above and in qt for the keyval are not invertible
1124 // so link to the QKeyEvent (which will vanish soon after return from the
1125 // event callback) to give plugins access to hardware_keycode and state.
1126 // (An XEvent would be nice but the QKeyEvent is good enough.)
1127 aEvent
.mPluginEvent
.Copy(*aQEvent
);
1131 nsWindow::keyPressEvent(QKeyEvent
* aEvent
)
1133 LOGFOCUS(("OnKeyPressEvent [%p]\n", (void *)this));
1135 // The user has done something.
1138 if (aEvent
->key() == Qt::Key_AltGr
) {
1139 sAltGrModifier
= true;
1142 // Before we dispatch a key, check if it's the context menu key.
1143 // If so, send a context menu key event instead.
1144 if (IsContextMenuKeyEvent(aEvent
)) {
1145 WidgetMouseEvent
contextMenuEvent(true, NS_CONTEXTMENU
, this,
1146 WidgetMouseEvent::eReal
,
1147 WidgetMouseEvent::eContextMenuKey
);
1148 return DispatchEvent(&contextMenuEvent
);
1151 //:TODO: fix shortcuts hebrew for non X11,
1152 //see Bug 562195##51
1154 uint32_t domKeyCode
= QtKeyCodeToDOMKeyCode(aEvent
->key());
1156 if (!aEvent
->isAutoRepeat() && !IsKeyDown(domKeyCode
)) {
1157 SetKeyDownFlag(domKeyCode
);
1159 WidgetKeyboardEvent
downEvent(true, NS_KEY_DOWN
, this);
1160 InitKeyEvent(downEvent
, aEvent
);
1162 nsEventStatus status
= DispatchEvent(&downEvent
);
1164 // DispatchEvent can Destroy us (bug 378273)
1165 if (MOZ_UNLIKELY(mIsDestroyed
)) {
1166 qWarning() << "Returning[" << __LINE__
<< "]: " << "Window destroyed";
1170 // If prevent default on keydown, don't dispatch keypress event
1171 if (status
== nsEventStatus_eConsumeNoDefault
) {
1172 return nsEventStatus_eConsumeNoDefault
;
1176 // Don't pass modifiers as NS_KEY_PRESS events.
1177 // Instead of selectively excluding some keys from NS_KEY_PRESS events,
1178 // we instead selectively include (as per MSDN spec
1179 // ( http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress%28VS.71%29.aspx );
1180 // no official spec covers KeyPress events).
1181 if (aEvent
->key() == Qt::Key_Shift
||
1182 aEvent
->key() == Qt::Key_Control
||
1183 aEvent
->key() == Qt::Key_Meta
||
1184 aEvent
->key() == Qt::Key_Alt
||
1185 aEvent
->key() == Qt::Key_AltGr
) {
1186 return nsEventStatus_eIgnore
;
1189 // Look for specialized app-command keys
1190 switch (aEvent
->key()) {
1192 return DispatchCommandEvent(nsGkAtoms::Back
);
1193 case Qt::Key_Forward
:
1194 return DispatchCommandEvent(nsGkAtoms::Forward
);
1195 case Qt::Key_Refresh
:
1196 return DispatchCommandEvent(nsGkAtoms::Reload
);
1198 return DispatchCommandEvent(nsGkAtoms::Stop
);
1199 case Qt::Key_Search
:
1200 return DispatchCommandEvent(nsGkAtoms::Search
);
1201 case Qt::Key_Favorites
:
1202 return DispatchCommandEvent(nsGkAtoms::Bookmarks
);
1203 case Qt::Key_HomePage
:
1204 return DispatchCommandEvent(nsGkAtoms::Home
);
1206 case Qt::Key_F16
: // F16, F20, F18, F14 are old keysyms for Copy Cut Paste Undo
1207 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_COPY
);
1210 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_CUT
);
1214 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_PASTE
);
1216 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_UNDO
);
1219 // Qt::Key_Redo and Qt::Key_Undo are not available yet.
1220 if (aEvent
->nativeVirtualKey() == 0xff66) {
1221 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_REDO
);
1223 if (aEvent
->nativeVirtualKey() == 0xff65) {
1224 return DispatchContentCommandEvent(NS_CONTENT_COMMAND_UNDO
);
1227 WidgetKeyboardEvent
event(true, NS_KEY_PRESS
, this);
1228 InitKeyEvent(event
, aEvent
);
1229 // Seend the key press event
1230 return DispatchEvent(&event
);
1234 nsWindow::keyReleaseEvent(QKeyEvent
* aEvent
)
1236 LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this));
1238 // The user has done something.
1241 if (IsContextMenuKeyEvent(aEvent
)) {
1242 // er, what do we do here? DoDefault or NoDefault?
1243 return nsEventStatus_eConsumeDoDefault
;
1246 // send the key event as a key up event
1247 WidgetKeyboardEvent
event(true, NS_KEY_UP
, this);
1248 InitKeyEvent(event
, aEvent
);
1250 if (aEvent
->key() == Qt::Key_AltGr
) {
1251 sAltGrModifier
= false;
1254 // unset the key down flag
1255 ClearKeyDownFlag(event
.keyCode
);
1257 return DispatchEvent(&event
);
1261 nsWindow::wheelEvent(QWheelEvent
* aEvent
)
1263 // check to see if we should rollup
1264 WidgetWheelEvent
wheelEvent(true, NS_WHEEL_WHEEL
, this);
1265 wheelEvent
.deltaMode
= nsIDOMWheelEvent::DOM_DELTA_LINE
;
1267 // negative values for aEvent->delta indicate downward scrolling;
1268 // this is opposite Gecko usage.
1269 // TODO: Store the unused delta values due to fraction round and add it
1270 // to next event. The stored values should be reset by other
1271 // direction scroll event.
1272 int32_t delta
= (int)(aEvent
->delta() / WHEEL_DELTA
) * -3;
1274 switch (aEvent
->orientation()) {
1276 wheelEvent
.deltaY
= wheelEvent
.lineOrPageDeltaY
= delta
;
1278 case Qt::Horizontal
:
1279 wheelEvent
.deltaX
= wheelEvent
.lineOrPageDeltaX
= delta
;
1286 wheelEvent
.refPoint
.x
= nscoord(aEvent
->pos().x());
1287 wheelEvent
.refPoint
.y
= nscoord(aEvent
->pos().y());
1289 wheelEvent
.InitBasicModifiers(aEvent
->modifiers() & Qt::ControlModifier
,
1290 aEvent
->modifiers() & Qt::AltModifier
,
1291 aEvent
->modifiers() & Qt::ShiftModifier
,
1292 aEvent
->modifiers() & Qt::MetaModifier
);
1293 wheelEvent
.time
= 0;
1295 return DispatchEvent(&wheelEvent
);
1299 nsWindow::showEvent(QShowEvent
*)
1301 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
,(void *)this));
1303 return nsEventStatus_eConsumeDoDefault
;
1307 nsWindow::hideEvent(QHideEvent
*)
1309 LOG(("%s [%p]\n", __PRETTY_FUNCTION__
,(void *)this));
1311 return nsEventStatus_eConsumeDoDefault
;
1314 nsEventStatus
nsWindow::touchEvent(QTouchEvent
* aEvent
)
1316 return nsEventStatus_eIgnore
;
1320 nsWindow::tabletEvent(QTabletEvent
* aEvent
)
1322 LOGFOCUS(("nsWindow::%s [%p]\n", __FUNCTION__
, (void *)this));
1323 return nsEventStatus_eIgnore
;
1329 nsWindow::DispatchEvent(WidgetGUIEvent
* aEvent
)
1331 nsEventStatus status
;
1332 DispatchEvent(aEvent
, status
);
1337 nsWindow::DispatchActivateEvent(void)
1339 if (mWidgetListener
) {
1340 mWidgetListener
->WindowActivated();
1345 nsWindow::DispatchDeactivateEvent(void)
1347 if (mWidgetListener
) {
1348 mWidgetListener
->WindowDeactivated();
1353 nsWindow::DispatchActivateEventOnTopLevelWindow(void)
1355 nsWindow
* topLevelWindow
= static_cast<nsWindow
*>(GetTopLevelWidget());
1356 if (topLevelWindow
!= nullptr) {
1357 topLevelWindow
->DispatchActivateEvent();
1362 nsWindow::DispatchDeactivateEventOnTopLevelWindow(void)
1364 nsWindow
* topLevelWindow
= static_cast<nsWindow
*>(GetTopLevelWidget());
1365 if (topLevelWindow
!= nullptr) {
1366 topLevelWindow
->DispatchDeactivateEvent();
1371 nsWindow::DispatchResizeEvent(nsIntRect
&aRect
, nsEventStatus
&aStatus
)
1373 aStatus
= nsEventStatus_eIgnore
;
1374 if (mWidgetListener
&&
1375 mWidgetListener
->WindowResized(this, aRect
.width
, aRect
.height
)) {
1376 aStatus
= nsEventStatus_eConsumeNoDefault
;
1380 ///////////////////////////////////// OLD GECKO ECENTS need to Sort ///////////////////
1382 NS_IMPL_ISUPPORTS_INHERITED(nsWindow
, nsBaseWidget
, nsISupportsWeakReference
)
1387 nsWindow::ClearCachedResources()
1389 if (mLayerManager
&&
1390 mLayerManager
->GetBackendType() == mozilla::layers::LayersBackend::LAYERS_BASIC
) {
1391 mLayerManager
->ClearCachedResources();
1393 for (nsIWidget
* kid
= mFirstChild
; kid
; ) {
1394 nsIWidget
* next
= kid
->GetNextSibling();
1395 static_cast<nsWindow
*>(kid
)->ClearCachedResources();
1401 nsWindow::SetParent(nsIWidget
*aNewParent
)
1403 NS_ENSURE_ARG_POINTER(aNewParent
);
1405 nsCOMPtr
<nsIWidget
> kungFuDeathGrip(this);
1406 nsIWidget
* parent
= GetParent();
1408 parent
->RemoveChild(this);
1410 ReparentNativeWidget(aNewParent
);
1411 aNewParent
->AddChild(this);
1416 nsWindow::SetModal(bool aModal
)
1418 LOG(("nsWindow::SetModal [%p] %d, widget[%p]\n", (void *)this, aModal
, mWidget
));
1420 mWidget
->setModality(aModal
? Qt::WindowModal
: Qt::NonModal
);
1428 nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement
,
1432 return NS_ERROR_NOT_IMPLEMENTED
;
1436 nsWindow::SetSizeMode(int32_t aMode
)
1440 LOG(("nsWindow::SetSizeMode [%p] %d\n", (void *)this, aMode
));
1441 if (aMode
!= nsSizeMode_Minimized
) {
1442 mWidget
->requestActivate();
1445 // Save the requested state.
1446 rv
= nsBaseWidget::SetSizeMode(aMode
);
1448 // return if there's no shell or our current state is the same as
1449 // the mode we were just set to.
1450 if (!mWidget
|| mSizeState
== mSizeMode
) {
1455 case nsSizeMode_Maximized
:
1456 mWidget
->showMaximized();
1458 case nsSizeMode_Minimized
:
1459 mWidget
->showMinimized();
1461 case nsSizeMode_Fullscreen
:
1462 mWidget
->showFullScreen();
1466 // nsSizeMode_Normal, really.
1471 mSizeState
= mSizeMode
;
1476 // Helper function to recursively find the first parent item that
1477 // is still visible (QGraphicsItem can be hidden even if they are
1478 // set to visible if one of their ancestors is invisible)
1480 void find_first_visible_parent(QWindow
* aItem
, QWindow
*& aVisibleItem
)
1482 NS_ENSURE_TRUE_VOID(aItem
);
1484 aVisibleItem
= nullptr;
1485 QWindow
* parItem
= nullptr;
1486 while (!aVisibleItem
) {
1487 if (aItem
->isVisible()) {
1488 aVisibleItem
= aItem
;
1491 parItem
= aItem
->parent();
1496 aItem
->setVisible(true);
1497 aVisibleItem
= aItem
;
1504 nsWindow::GetScreenBounds(nsIntRect
&aRect
)
1506 aRect
= nsIntRect(nsIntPoint(0, 0), mBounds
.Size());
1508 QPoint pos
= mWidget
->position();
1509 aRect
.MoveTo(pos
.x(), pos
.y());
1512 aRect
.MoveTo(WidgetToScreenOffset());
1514 LOG(("GetScreenBounds %d %d | %d %d | %d %d\n",
1516 mBounds
.width
, mBounds
.height
,
1517 aRect
.width
, aRect
.height
));
1522 nsWindow::SetIcon(const nsAString
& aIconSpec
)
1527 nsCOMPtr
<nsIFile
> iconFile
;
1529 nsTArray
<nsCString
> iconList
;
1531 // Look for icons with the following suffixes appended to the base name.
1532 // The last two entries (for the old XPM format) will be ignored unless
1533 // no icons are found using the other suffixes. XPM icons are depricated.
1535 const char extensions
[6][7] = { ".png", "16.png", "32.png", "48.png",
1538 for (uint32_t i
= 0; i
< ArrayLength(extensions
); i
++) {
1539 // Don't bother looking for XPM versions if we found a PNG.
1540 if (i
== ArrayLength(extensions
) - 2 && iconList
.Length())
1543 nsAutoString extension
;
1544 extension
.AppendASCII(extensions
[i
]);
1546 ResolveIconName(aIconSpec
, extension
, getter_AddRefs(iconFile
));
1548 iconFile
->GetNativePath(path
);
1549 iconList
.AppendElement(path
);
1553 // leave the default icon intact if no matching icons were found
1554 if (iconList
.Length() == 0)
1557 return SetWindowIconList(iconList
);
1561 nsWindow::CaptureMouse(bool aCapture
)
1563 LOG(("CaptureMouse %p\n", (void *)this));
1568 mWidget
->setMouseGrabEnabled(aCapture
);
1574 nsWindow::CheckForRollup(double aMouseX
, double aMouseY
,
1577 nsIRollupListener
* rollupListener
= GetActiveRollupListener();
1578 nsCOMPtr
<nsIWidget
> rollupWidget
;
1579 if (rollupListener
) {
1580 rollupWidget
= rollupListener
->GetRollupWidget();
1582 if (!rollupWidget
) {
1583 nsBaseWidget::gRollupListener
= nullptr;
1587 bool retVal
= false;
1588 MozQWidget
*currentPopup
=
1589 (MozQWidget
*)rollupWidget
->GetNativeData(NS_NATIVE_WINDOW
);
1590 if (!is_mouse_in_window(currentPopup
, aMouseX
, aMouseY
)) {
1593 rollup
= rollupListener
->ShouldRollupOnMouseWheelEvent();
1596 // if we're dealing with menus, we probably have submenus and
1597 // we don't want to rollup if the clickis in a parent menu of
1598 // the current submenu
1599 uint32_t popupsToRollup
= UINT32_MAX
;
1600 if (rollupListener
) {
1601 nsAutoTArray
<nsIWidget
*, 5> widgetChain
;
1602 uint32_t sameTypeCount
= rollupListener
->GetSubmenuWidgetChain(&widgetChain
);
1603 for (uint32_t i
=0; i
<widgetChain
.Length(); ++i
) {
1604 nsIWidget
* widget
= widgetChain
[i
];
1605 MozQWidget
* currWindow
=
1606 (MozQWidget
*) widget
->GetNativeData(NS_NATIVE_WINDOW
);
1607 if (is_mouse_in_window(currWindow
, aMouseX
, aMouseY
)) {
1608 if (i
< sameTypeCount
) {
1612 popupsToRollup
= sameTypeCount
;
1616 } // foreach parent menu widget
1617 } // if rollup listener knows about menus
1619 // if we've determined that we should still rollup, do it.
1621 nsIntPoint
pos(aMouseX
, aMouseY
);
1622 retVal
= rollupListener
->Rollup(popupsToRollup
, &pos
, nullptr);
1631 is_mouse_in_window (MozQWidget
* aWindow
, double aMouseX
, double aMouseY
)
1633 return aWindow
->geometry().contains(aMouseX
, aMouseY
);
1637 nsWindow::GetAttention(int32_t aCycleCount
)
1639 LOG(("nsWindow::GetAttention [%p]\n", (void *)this));
1640 return NS_ERROR_NOT_IMPLEMENTED
;
1646 nsWindow::OnCloseEvent(QCloseEvent
*aEvent
)
1648 if (!mWidgetListener
)
1649 return nsEventStatus_eIgnore
;
1650 mWidgetListener
->RequestWindowClose(this);
1651 return nsEventStatus_eConsumeNoDefault
;
1656 is_latin_shortcut_key(quint32 aKeyval
)
1658 return ((Qt::Key_0
<= aKeyval
&& aKeyval
<= Qt::Key_9
) ||
1659 (Qt::Key_A
<= aKeyval
&& aKeyval
<= Qt::Key_Z
));
1663 nsWindow::DispatchCommandEvent(nsIAtom
* aCommand
)
1665 WidgetCommandEvent
event(true, nsGkAtoms::onAppCommand
, aCommand
, this);
1667 nsEventStatus status
;
1668 DispatchEvent(&event
, status
);
1674 nsWindow::DispatchContentCommandEvent(int32_t aMsg
)
1676 WidgetContentCommandEvent
event(true, aMsg
, this);
1678 nsEventStatus status
;
1679 DispatchEvent(&event
, status
);
1686 GetBrandName(nsXPIDLString
& brandName
)
1688 nsCOMPtr
<nsIStringBundleService
> bundleService
=
1689 mozilla::services::GetStringBundleService();
1691 nsCOMPtr
<nsIStringBundle
> bundle
;
1692 if (bundleService
) {
1693 bundleService
->CreateBundle(
1694 "chrome://branding/locale/brand.properties",
1695 getter_AddRefs(bundle
));
1699 bundle
->GetStringFromName(
1700 MOZ_UTF16("brandShortName"),
1701 getter_Copies(brandName
));
1704 if (brandName
.IsEmpty()) {
1705 brandName
.AssignLiteral(MOZ_UTF16("Mozilla"));
1710 nsWindow::SetWindowClass(const nsAString
&xulWinType
)
1713 return NS_ERROR_FAILURE
;
1716 nsXPIDLString brandName
;
1717 GetBrandName(brandName
);
1720 XClassHint
*class_hint
= XAllocClassHint();
1722 return NS_ERROR_OUT_OF_MEMORY
;
1724 const char *role
= nullptr;
1725 class_hint
->res_name
= ToNewCString(xulWinType
);
1726 if (!class_hint
->res_name
) {
1728 return NS_ERROR_OUT_OF_MEMORY
;
1730 class_hint
->res_class
= ToNewCString(brandName
);
1731 if (!class_hint
->res_class
) {
1732 nsMemory::Free(class_hint
->res_name
);
1734 return NS_ERROR_OUT_OF_MEMORY
;
1737 // Parse res_name into a name and role. Characters other than
1738 // [A-Za-z0-9_-] are converted to '_'. Anything after the first
1739 // colon is assigned to role; if there's no colon, assign the
1740 // whole thing to both role and res_name.
1741 for (char *c
= class_hint
->res_name
; *c
; c
++) {
1746 else if (!isascii(*c
) || (!isalnum(*c
) && ('_' != *c
) && ('-' != *c
)))
1749 class_hint
->res_name
[0] = toupper(class_hint
->res_name
[0]);
1750 if (!role
) role
= class_hint
->res_name
;
1752 QWindow
*widget
= mWidget
;
1753 // If widget not show, handle might be null
1754 if (widget
&& widget
->winId()) {
1755 XSetClassHint(gfxQtPlatform::GetXDisplay(widget
),
1760 nsMemory::Free(class_hint
->res_class
);
1761 nsMemory::Free(class_hint
->res_name
);
1769 nsWindow::NativeResize(int32_t aWidth
, int32_t aHeight
, bool aRepaint
)
1771 LOG(("nsWindow::NativeResize [%p] %d %d\n", (void *)this,
1774 mNeedsResize
= false;
1776 mWidget
->resize(aWidth
, aHeight
);
1779 mWidget
->renderLater();
1784 nsWindow::NativeResize(int32_t aX
, int32_t aY
,
1785 int32_t aWidth
, int32_t aHeight
,
1788 LOG(("nsWindow::NativeResize [%p] %d %d %d %d\n", (void *)this,
1789 aX
, aY
, aWidth
, aHeight
));
1791 mNeedsResize
= false;
1794 mWidget
->setGeometry(aX
, aY
, aWidth
, aHeight
);
1797 mWidget
->renderLater();
1802 nsWindow::NativeShow(bool aAction
)
1805 // On e10s, we never want the child process or plugin process
1806 // to go fullscreen because if we do the window because visible
1807 // do to disabled Qt-Xembed
1809 // unset our flag now that our window has been shown
1818 nsWindow::SetHasTransparentBackground(bool aTransparent
)
1820 return NS_ERROR_NOT_IMPLEMENTED
;
1824 nsWindow::GetHasTransparentBackground(bool& aTransparent
)
1826 aTransparent
= mIsTransparent
;
1831 nsWindow::SetupPluginPort(void)
1833 NS_WARNING("Not implemented");
1838 nsWindow::SetWindowIconList(const nsTArray
<nsCString
> &aIconList
)
1842 for (uint32_t i
= 0; i
< aIconList
.Length(); ++i
) {
1843 const char *path
= aIconList
[i
].get();
1844 LOG(("window [%p] Loading icon from %s\n", (void *)this, path
));
1848 mWidget
->setIcon(icon
);
1854 nsWindow::SetDefaultIcon(void)
1856 SetIcon(NS_LITERAL_STRING("default"));
1859 void nsWindow::QWidgetDestroyed()
1866 nsWindow::HideWindowChrome(bool aShouldHide
)
1870 return NS_ERROR_FAILURE
;
1873 // Sawfish, metacity, and presumably other window managers get
1874 // confused if we change the window decorations while the window
1876 bool wasVisible
= false;
1877 if (mWidget
->isVisible()) {
1889 //////////////////////////////////////////////////////////////////////
1891 NS_IMETHODIMP_(bool)
1892 nsWindow::HasGLContext()
1899 nsWindow::GetParent(void)
1907 return qApp
->primaryScreen()->logicalDotsPerInch();
1911 nsWindow::OnDestroy(void)
1913 if (mOnDestroyCalled
) {
1917 mOnDestroyCalled
= true;
1919 // release references to children and device context
1920 nsBaseWidget::OnDestroy();
1922 // let go of our parent
1925 nsCOMPtr
<nsIWidget
> kungFuDeathGrip
= this;
1926 NotifyWindowDestroyed();
1930 nsWindow::AreBoundsSane(void)
1932 if (mBounds
.width
> 0 && mBounds
.height
> 0) {
1940 nsWindow::SetSoftwareKeyboardState(bool aOpen
,
1941 const InputContextAction
& aAction
)
1944 NS_ENSURE_TRUE_VOID(mInputContext
.mIMEState
.mEnabled
!=
1945 IMEState::DISABLED
);
1947 // Ensure that opening the virtual keyboard is allowed for this specific
1948 // InputContext depending on the content.ime.strict.policy pref
1949 if (mInputContext
.mIMEState
.mEnabled
!= IMEState::PLUGIN
&&
1950 Preferences::GetBool("content.ime.strict_policy", false) &&
1951 !aAction
.ContentGotFocusByTrustedCause() &&
1952 !aAction
.UserMightRequestOpenVKB()) {
1958 qApp
->inputMethod()->show();
1960 qApp
->inputMethod()->hide();
1968 nsWindow::ProcessMotionEvent()
1970 if (mMoveEvent
.needDispatch
) {
1971 WidgetMouseEvent
event(true, NS_MOUSE_MOVE
, this,
1972 WidgetMouseEvent::eReal
);
1974 event
.refPoint
.x
= nscoord(mMoveEvent
.pos
.x());
1975 event
.refPoint
.y
= nscoord(mMoveEvent
.pos
.y());
1977 event
.InitBasicModifiers(mMoveEvent
.modifiers
& Qt::ControlModifier
,
1978 mMoveEvent
.modifiers
& Qt::AltModifier
,
1979 mMoveEvent
.modifiers
& Qt::ShiftModifier
,
1980 mMoveEvent
.modifiers
& Qt::MetaModifier
);
1981 event
.clickCount
= 0;
1983 DispatchEvent(&event
);
1984 mMoveEvent
.needDispatch
= false;
1987 mTimerStarted
= false;