Advertisement
Guest User

Untitled

a guest
Jun 28th, 2012
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.90 KB | None | 0 0
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* vim: set ts=4 et sw=4 tw=80: */
  3. /* This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6.  
  7. #include <QGraphicsSceneHoverEvent>
  8. #include <QGraphicsSceneMouseEvent>
  9. #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
  10. #include <QInputContext>
  11. #endif
  12. #include <QtCore/QTimer>
  13.  
  14. #include "mozqwidget.h"
  15. #include "nsWindow.h"
  16.  
  17. #include "nsIObserverService.h"
  18. #include "mozilla/Services.h"
  19.  
  20. #include <QDebug>
  21.  
  22. #ifdef MOZ_ENABLE_QTMOBILITY
  23. #if (MOZ_PLATFORM_MAEMO == 5)
  24. #include <QApplication>
  25. #include <QDesktopWidget>
  26. #else
  27. #include "mozqorientationsensorfilter.h"
  28. #ifdef MOZ_X11
  29. #include <QX11Info>
  30. #include <X11/Xlib.h>
  31. #include <X11/Xatom.h>
  32. # undef KeyPress
  33. # undef KeyRelease
  34. # undef CursorShape
  35. #endif //MOZ_X11
  36. #endif //!(MOZ_PLATFORM_MAEMO == 5)
  37. #endif //MOZ_ENABLE_QTMOBILITY
  38.  
  39. /*
  40. Pure Qt is lacking a clear API to get the current state of the VKB (opened
  41. or closed).
  42. */
  43. static bool gKeyboardOpen = false;
  44.  
  45. /*
  46. In case we could not open the keyboard, we will try again when the focus
  47. event is sent. This can happen if the keyboard is asked for before the
  48. window is focused. This global is used to track that case.
  49. */
  50. static bool gFailedOpenKeyboard = false;
  51.  
  52. /*
  53. For websites that focus editable elements during other operations for a very
  54. short time, we add some decoupling to prevent the VKB from appearing and
  55. reappearing for a very short time. This global is set when the keyboard should
  56. be opened and if it is still set when a timer runs out, the VKB is really
  57. shown.
  58. */
  59. static bool gPendingVKBOpen = false;
  60.  
  61. /*
  62. Contains the last preedit String, this is needed in order to generate KeyEvents
  63. */
  64. static QString gLastPreeditString;
  65.  
  66. MozQWidget::MozQWidget(nsWindow* aReceiver, QGraphicsItem* aParent)
  67. : mReceiver(aReceiver)
  68. {
  69. setParentItem(aParent);
  70. #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
  71. setFlag(QGraphicsItem::ItemAcceptsInputMethod);
  72. setAcceptTouchEvents(true);
  73. #endif
  74. setAcceptHoverEvents(true);
  75. }
  76.  
  77. MozQWidget::~MozQWidget()
  78. {
  79. if (mReceiver)
  80. mReceiver->QWidgetDestroyed();
  81. }
  82.  
  83. void MozQWidget::paint(QPainter* aPainter, const QStyleOptionGraphicsItem* aOption, QWidget* aWidget /*= 0*/)
  84. {
  85. mReceiver->DoPaint(aPainter, aOption, aWidget);
  86. }
  87.  
  88. void MozQWidget::activate()
  89. {
  90. // ensure that the keyboard is hidden when we activate the window
  91. hideVKB();
  92. mReceiver->DispatchActivateEventOnTopLevelWindow();
  93. }
  94.  
  95. void MozQWidget::deactivate()
  96. {
  97. // ensure that the keyboard is hidden when we deactivate the window
  98. hideVKB();
  99. mReceiver->DispatchDeactivateEventOnTopLevelWindow();
  100. }
  101.  
  102. void MozQWidget::resizeEvent(QGraphicsSceneResizeEvent* aEvent)
  103. {
  104. mReceiver->OnResizeEvent(aEvent);
  105. }
  106.  
  107. void MozQWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent* aEvent)
  108. {
  109. mReceiver->contextMenuEvent(aEvent);
  110. }
  111.  
  112. void MozQWidget::dragEnterEvent(QGraphicsSceneDragDropEvent* aEvent)
  113. {
  114. mReceiver->OnDragEnter(aEvent);
  115. }
  116.  
  117. void MozQWidget::dragLeaveEvent(QGraphicsSceneDragDropEvent* aEvent)
  118. {
  119. mReceiver->OnDragLeaveEvent(aEvent);
  120. }
  121.  
  122. void MozQWidget::dragMoveEvent(QGraphicsSceneDragDropEvent* aEvent)
  123. {
  124. mReceiver->OnDragMotionEvent(aEvent);
  125. }
  126.  
  127. void MozQWidget::dropEvent(QGraphicsSceneDragDropEvent* aEvent)
  128. {
  129. mReceiver->OnDragDropEvent(aEvent);
  130. }
  131.  
  132. void MozQWidget::focusInEvent(QFocusEvent* aEvent)
  133. {
  134. mReceiver->OnFocusInEvent(aEvent);
  135.  
  136. // The application requested the VKB during startup but did not manage
  137. // to open it, because there was no focused window yet so we do it now by
  138. // requesting the VKB without any timeout.
  139. if (gFailedOpenKeyboard)
  140. requestVKB(0, this);
  141. }
  142.  
  143. #ifdef MOZ_ENABLE_QTMOBILITY
  144. void MozQWidget::orientationChanged()
  145. {
  146. if (!scene() || !scene()->views().size()) {
  147. return;
  148. }
  149.  
  150. NS_ASSERTION(scene()->views().size() == 1, "Not exactly one view for our scene!");
  151. #if (MOZ_PLATFORM_MAEMO == 5)
  152. QRect screenGeometry = QApplication::desktop()->screenGeometry();
  153.  
  154. if(mReceiver)
  155. qDebug() << mReceiver->mBounds.x
  156. << mReceiver->mBounds.y
  157. << mReceiver->mBounds.width
  158. << mReceiver->mBounds.height;
  159.  
  160. resize(screenGeometry.size());
  161. scene()->setSceneRect(QRectF(QPointF(0, 0), screenGeometry.size()));
  162. scene()->views()[0]->resize(screenGeometry.size());
  163. #else
  164. QTransform& transform = MozQOrientationSensorFilter::GetRotationTransform();
  165. QRect scrTrRect = transform.mapRect(scene()->views()[0]->rect());
  166.  
  167. setTransformOriginPoint(scene()->views()[0]->size().width() / 2, scene()->views()[0]->size().height() / 2);
  168. scene()->views()[0]->setTransform(transform);
  169. int orientation = MozQOrientationSensorFilter::GetWindowRotationAngle();
  170. if (orientation == 0 || orientation == 180) {
  171. setPos(0,0);
  172. } else {
  173. setPos(-(scrTrRect.size().width() - scrTrRect.size().height()) / 2,
  174. (scrTrRect.size().width() - scrTrRect.size().height()) / 2);
  175. }
  176. resize(scrTrRect.size());
  177. scene()->setSceneRect(QRectF(QPointF(0, 0), scrTrRect.size()));
  178. #ifdef MOZ_X11
  179. Display* display = QX11Info::display();
  180. if (!display) {
  181. return;
  182. }
  183.  
  184. Atom orientationAngleAtom = XInternAtom(display, "_MEEGOTOUCH_ORIENTATION_ANGLE", False);
  185. XChangeProperty(display, scene()->views()[0]->effectiveWinId(),
  186. orientationAngleAtom, XA_CARDINAL, 32,
  187. PropModeReplace, (unsigned char*)&orientation, 1);
  188. #endif
  189. #endif
  190. }
  191. #endif
  192.  
  193. void MozQWidget::focusOutEvent(QFocusEvent* aEvent)
  194. {
  195. mReceiver->OnFocusOutEvent(aEvent);
  196. //OtherFocusReason most like means VKB was closed manual (done button)
  197. if (aEvent->reason() == Qt::OtherFocusReason && gKeyboardOpen) {
  198. hideVKB();
  199. }
  200. }
  201.  
  202. void MozQWidget::hoverEnterEvent(QGraphicsSceneHoverEvent* aEvent)
  203. {
  204. mReceiver->OnEnterNotifyEvent(aEvent);
  205. }
  206.  
  207. void MozQWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent* aEvent)
  208. {
  209. mReceiver->OnLeaveNotifyEvent(aEvent);
  210. }
  211.  
  212. void MozQWidget::hoverMoveEvent(QGraphicsSceneHoverEvent* aEvent)
  213. {
  214. mReceiver->OnMotionNotifyEvent(aEvent->pos(), aEvent->modifiers());
  215. }
  216.  
  217. void MozQWidget::keyPressEvent(QKeyEvent* aEvent)
  218. {
  219. #if (MOZ_PLATFORM_MAEMO == 6)
  220. if (!gKeyboardOpen ||
  221. //those might get sended as KeyEvents, even in 'NormalMode'
  222. aEvent->key() == Qt::Key_Space ||
  223. aEvent->key() == Qt::Key_Return ||
  224. aEvent->key() == Qt::Key_Backspace) {
  225. mReceiver->OnKeyPressEvent(aEvent);
  226. }
  227. #elif (MOZ_PLATFORM_MAEMO == 5)
  228. // Below removed to prevent invertion of upper and lower case
  229. // See bug 561234
  230. // mReceiver->OnKeyPressEvent(aEvent);
  231. #else
  232. mReceiver->OnKeyPressEvent(aEvent);
  233. #endif
  234. }
  235.  
  236. void MozQWidget::keyReleaseEvent(QKeyEvent* aEvent)
  237. {
  238. #if (MOZ_PLATFORM_MAEMO == 6)
  239. if (!gKeyboardOpen ||
  240. //those might get sended as KeyEvents, even in 'NormalMode'
  241. aEvent->key() == Qt::Key_Space ||
  242. aEvent->key() == Qt::Key_Return ||
  243. aEvent->key() == Qt::Key_Backspace) {
  244. mReceiver->OnKeyReleaseEvent(aEvent);
  245. }
  246. return;
  247. #elif (MOZ_PLATFORM_MAEMO == 5)
  248. // Below line should be removed when bug 561234 is fixed
  249. mReceiver->OnKeyPressEvent(aEvent);
  250. #endif
  251. mReceiver->OnKeyReleaseEvent(aEvent);
  252. }
  253.  
  254. void MozQWidget::inputMethodEvent(QInputMethodEvent* aEvent)
  255. {
  256. QString currentPreeditString = aEvent->preeditString();
  257. QString currentCommitString = aEvent->commitString();
  258.  
  259. //first check for some controllkeys send as text...
  260. if (currentCommitString == " ") {
  261. sendPressReleaseKeyEvent(Qt::Key_Space, currentCommitString.unicode());
  262. } else if (currentCommitString == "\n") {
  263. sendPressReleaseKeyEvent(Qt::Key_Return, currentCommitString.unicode());
  264. } else if (currentCommitString.isEmpty()) {
  265. //if its no controllkey than check if current Commit is empty
  266. //if yes than we have some preedit text here
  267. if (currentPreeditString.length() == 1 && gLastPreeditString.isEmpty()) {
  268. //Preedit text can change its entire look'a'like
  269. //check if length of new compared to the old is 1,
  270. //means that its a new startup
  271. sendPressReleaseKeyEvent(0, currentPreeditString.unicode());
  272. } else if (currentPreeditString.startsWith(gLastPreeditString)) {
  273. //Length was not 1 or not a new startup
  274. //check if the current preedit starts with the last one,
  275. //if so: Add new letters (note: this can be more then one new letter)
  276. const QChar * text = currentPreeditString.unicode();
  277. for (int i = gLastPreeditString.length(); i < currentPreeditString.length(); i++) {
  278. sendPressReleaseKeyEvent(0, &text[i]);
  279. }
  280. } else {
  281. //last possible case, we had a PreeditString which was now completely changed.
  282. //first, check if just one letter was removed (normal Backspace case!)
  283. //if so: just send the backspace
  284. QString tempLastPre = gLastPreeditString;
  285. tempLastPre.truncate(gLastPreeditString.length()-1);
  286. if (currentPreeditString == tempLastPre) {
  287. sendPressReleaseKeyEvent(Qt::Key_Backspace);
  288. } else if (currentPreeditString != tempLastPre) {
  289. //more than one character changed, so just renew everything
  290. //delete all preedit
  291. for (int i = 0; i < gLastPreeditString.length(); i++) {
  292. sendPressReleaseKeyEvent(Qt::Key_Backspace);
  293. }
  294. //send new Preedit
  295. const QChar * text = currentPreeditString.unicode();
  296. for (int i = 0; i < currentPreeditString.length(); i++) {
  297. sendPressReleaseKeyEvent(0, &text[i]);
  298. }
  299. }
  300. }
  301. } else if (gLastPreeditString != currentCommitString) {
  302. //User commited something
  303. if (currentCommitString.length() == 1 && gLastPreeditString.isEmpty()) {
  304. //if commit string ist one and there is no Preedit String
  305. //case i.e. when no error correction is enabled in the system (default meego.com)
  306. sendPressReleaseKeyEvent(0, currentCommitString.unicode());
  307. } else {
  308. //There is a Preedit, first remove it
  309. for (int i = 0; i < gLastPreeditString.length(); i++) {
  310. sendPressReleaseKeyEvent(Qt::Key_Backspace);
  311. }
  312. //Now push commited String into
  313. const QChar * text = currentCommitString.unicode();
  314. for (int i = 0; i < currentCommitString.length(); i++) {
  315. sendPressReleaseKeyEvent(0, &text[i]);
  316. }
  317. }
  318. }
  319.  
  320. //save preedit for next round.
  321. gLastPreeditString = currentPreeditString;
  322.  
  323. //pre edit is continues string of new chars pressed by the user.
  324. //if pre edit is changing rapidly without commit string first then user choose some overed text
  325. //if commitstring comes directly after, forget about it
  326. QGraphicsWidget::inputMethodEvent(aEvent);
  327. }
  328.  
  329. void MozQWidget::sendPressReleaseKeyEvent(int key,
  330. const QChar* letter,
  331. bool autorep,
  332. ushort count)
  333. {
  334. Qt::KeyboardModifiers modifiers = Qt::NoModifier;
  335. if (letter && letter->isUpper()) {
  336. modifiers = Qt::ShiftModifier;
  337. }
  338.  
  339. if (letter) {
  340. // Handle as TextEvent
  341. nsCompositionEvent start(true, NS_COMPOSITION_START, mReceiver);
  342. mReceiver->DispatchEvent(&start);
  343.  
  344. nsTextEvent text(true, NS_TEXT_TEXT, mReceiver);
  345. QString commitString = QString(*letter);
  346. text.theText.Assign(commitString.utf16());
  347. mReceiver->DispatchEvent(&text);
  348.  
  349. nsCompositionEvent end(true, NS_COMPOSITION_END, mReceiver);
  350. mReceiver->DispatchEvent(&end);
  351. return;
  352. }
  353.  
  354. QKeyEvent press(QEvent::KeyPress, key, modifiers, QString(), autorep, count);
  355. mReceiver->OnKeyPressEvent(&press);
  356. QKeyEvent release(QEvent::KeyRelease, key, modifiers, QString(), autorep, count);
  357. mReceiver->OnKeyReleaseEvent(&release);
  358. }
  359.  
  360. void MozQWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* aEvent)
  361. {
  362. // Qt sends double click event, but not second press event.
  363. mReceiver->OnButtonPressEvent(aEvent);
  364. mReceiver->OnMouseDoubleClickEvent(aEvent);
  365. }
  366.  
  367. void MozQWidget::mouseMoveEvent(QGraphicsSceneMouseEvent* aEvent)
  368. {
  369. mReceiver->OnMotionNotifyEvent(aEvent->pos(), aEvent->modifiers());
  370. }
  371.  
  372. void MozQWidget::mousePressEvent(QGraphicsSceneMouseEvent* aEvent)
  373. {
  374. mReceiver->OnButtonPressEvent(aEvent);
  375. }
  376.  
  377. void MozQWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent* aEvent)
  378. {
  379. mReceiver->OnButtonReleaseEvent(aEvent);
  380. }
  381.  
  382. bool MozQWidget::event ( QEvent * event )
  383. {
  384. // check receiver, since due to deleteLater() call it's possible, that
  385. // events pass loop after receiver's destroy and while widget is still alive
  386. if (!mReceiver)
  387. return QGraphicsWidget::event(event);
  388.  
  389. #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0))
  390. switch (event->type())
  391. {
  392. case QEvent::TouchBegin:
  393. case QEvent::TouchEnd:
  394. case QEvent::TouchUpdate:
  395. {
  396. // Do not send this event to other handlers, this is needed
  397. // to be able to receive the gesture events
  398. bool handled = false;
  399. mReceiver->OnTouchEvent(static_cast<QTouchEvent *>(event),handled);
  400. return handled;
  401. }
  402. case (QEvent::Gesture):
  403. {
  404. bool handled = false;
  405. mReceiver->OnGestureEvent(static_cast<QGestureEvent*>(event),handled);
  406. return handled;
  407. }
  408. default:
  409. break;
  410. }
  411. #endif
  412. return QGraphicsWidget::event(event);
  413. }
  414.  
  415. void MozQWidget::wheelEvent(QGraphicsSceneWheelEvent* aEvent)
  416. {
  417. mReceiver->OnScrollEvent(aEvent);
  418. }
  419.  
  420. void MozQWidget::closeEvent(QCloseEvent* aEvent)
  421. {
  422. mReceiver->OnCloseEvent(aEvent);
  423. }
  424.  
  425. void MozQWidget::hideEvent(QHideEvent* aEvent)
  426. {
  427. mReceiver->hideEvent(aEvent);
  428. QGraphicsWidget::hideEvent(aEvent);
  429. }
  430.  
  431. void MozQWidget::showEvent(QShowEvent* aEvent)
  432. {
  433. mReceiver->showEvent(aEvent);
  434. QGraphicsWidget::showEvent(aEvent);
  435. }
  436.  
  437. bool MozQWidget::SetCursor(nsCursor aCursor)
  438. {
  439. Qt::CursorShape cursor = Qt::ArrowCursor;
  440. switch(aCursor) {
  441. case eCursor_standard:
  442. cursor = Qt::ArrowCursor;
  443. break;
  444. case eCursor_wait:
  445. cursor = Qt::WaitCursor;
  446. break;
  447. case eCursor_select:
  448. cursor = Qt::IBeamCursor;
  449. break;
  450. case eCursor_hyperlink:
  451. cursor = Qt::PointingHandCursor;
  452. break;
  453. case eCursor_ew_resize:
  454. cursor = Qt::SplitHCursor;
  455. break;
  456. case eCursor_ns_resize:
  457. cursor = Qt::SplitVCursor;
  458. break;
  459. case eCursor_nw_resize:
  460. case eCursor_se_resize:
  461. cursor = Qt::SizeBDiagCursor;
  462. break;
  463. case eCursor_ne_resize:
  464. case eCursor_sw_resize:
  465. cursor = Qt::SizeFDiagCursor;
  466. break;
  467. case eCursor_crosshair:
  468. case eCursor_move:
  469. cursor = Qt::SizeAllCursor;
  470. break;
  471. case eCursor_help:
  472. cursor = Qt::WhatsThisCursor;
  473. break;
  474. case eCursor_copy:
  475. case eCursor_alias:
  476. break;
  477. case eCursor_context_menu:
  478. case eCursor_cell:
  479. case eCursor_grab:
  480. case eCursor_grabbing:
  481. case eCursor_spinning:
  482. case eCursor_zoom_in:
  483. case eCursor_zoom_out:
  484.  
  485. default:
  486. break;
  487. }
  488.  
  489. setCursor(cursor);
  490.  
  491. return NS_OK;
  492. }
  493.  
  494. bool MozQWidget::SetCursor(const QPixmap& aCursor, int aHotX, int aHotY)
  495. {
  496. QCursor bitmapCursor(aCursor, aHotX, aHotY);
  497. setCursor(bitmapCursor);
  498.  
  499. return NS_OK;
  500. }
  501.  
  502. void MozQWidget::setModal(bool modal)
  503. {
  504. #if QT_VERSION >= 0x040600
  505. setPanelModality(modal ? QGraphicsItem::SceneModal : QGraphicsItem::NonModal);
  506. #else
  507. LOG(("Modal QGraphicsWidgets not supported in Qt < 4.6\n"));
  508. #endif
  509. }
  510.  
  511. QVariant MozQWidget::inputMethodQuery(Qt::InputMethodQuery aQuery) const
  512. {
  513. // Additional MeeGo Touch queries, which do not depend on actually
  514. // having a focused input field.
  515. switch ((int) aQuery) {
  516. case 10001: // VisualizationPriorityQuery.
  517. // Tells if input method widget wants to have high priority
  518. // for visualization. Input methods should honor this and stay
  519. // out of widgets space.
  520. // Return false, eg. the input method can overlap QGraphicsWKView.
  521. return QVariant(false);
  522. case 10003: // ImCorrectionEnabledQuery.
  523. // Explicit correction enabling for text entries.
  524. return QVariant(false);
  525. case 10004: // ImModeQuery.
  526. // Retrieval mode: normal (0), direct [minics hardware keyboard] (1) or proxy (2)
  527. return QVariant::fromValue(0);
  528. case 10006: // InputMethodToolbarQuery.
  529. // Custom toolbar file name for text entry.
  530. return QVariant();
  531. }
  532.  
  533. // Standard Qt queries dependent on having a focused web text input.
  534. switch (aQuery) {
  535. case Qt::ImFont:
  536. return QVariant(QFont());
  537. case Qt::ImMaximumTextLength:
  538. return QVariant(); // Means no limit.
  539. }
  540.  
  541. // Additional MeeGo Touch queries dependent on having a focused web text input
  542. switch ((int) aQuery) {
  543. case 10002: // PreeditRectangleQuery.
  544. // Retrieve bounding rectangle for current preedit text.
  545. return QVariant(QRect());
  546. }
  547.  
  548. return QVariant();
  549. }
  550.  
  551. /**
  552. Request the VKB and starts a timer with the given timeout in milliseconds.
  553. If the request is not canceled when the timer runs out, the VKB is actually
  554. shown.
  555. */
  556. void MozQWidget::requestVKB(int aTimeout, QObject* aWidget)
  557. {
  558. if (!gPendingVKBOpen) {
  559. gPendingVKBOpen = true;
  560.  
  561. if (aTimeout == 0 || !aWidget) {
  562. showVKB();
  563. } else {
  564. QTimer::singleShot(aTimeout, aWidget, SLOT(showVKB()));
  565. }
  566. }
  567. }
  568.  
  569. void MozQWidget::showVKB()
  570. {
  571. // skip showing of keyboard if not pending
  572. if (!gPendingVKBOpen) {
  573. return;
  574. }
  575.  
  576. gPendingVKBOpen = false;
  577.  
  578. #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
  579. QWidget* focusWidget = qApp->focusWidget();
  580.  
  581. if (focusWidget) {
  582. QInputContext *inputContext = qApp->inputContext();
  583. if (!inputContext) {
  584. NS_WARNING("Requesting SIP: but no input context");
  585. return;
  586. }
  587.  
  588. QEvent request(QEvent::RequestSoftwareInputPanel);
  589. inputContext->filterEvent(&request);
  590. focusWidget->setAttribute(Qt::WA_InputMethodEnabled, true);
  591. inputContext->setFocusWidget(focusWidget);
  592. gKeyboardOpen = true;
  593. gFailedOpenKeyboard = false;
  594. }
  595. else
  596. {
  597. // No focused widget yet, so we have to open the VKB later on.
  598. gFailedOpenKeyboard = true;
  599. }
  600. #else
  601. LOG(("VKB not supported in Qt < 4.6\n"));
  602. #endif
  603. }
  604.  
  605. void MozQWidget::hideVKB()
  606. {
  607. if (gPendingVKBOpen) {
  608. // do not really open
  609. gPendingVKBOpen = false;
  610. }
  611.  
  612. if (!gKeyboardOpen) {
  613. return;
  614. }
  615.  
  616. #if (QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)) && (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
  617. QInputContext *inputContext = qApp->inputContext();
  618. if (!inputContext) {
  619. NS_WARNING("Closing SIP: but no input context");
  620. return;
  621. }
  622.  
  623. QEvent request(QEvent::CloseSoftwareInputPanel);
  624. inputContext->filterEvent(&request);
  625. inputContext->reset();
  626. gKeyboardOpen = false;
  627. #else
  628. LOG(("VKB not supported in Qt < 4.6\n"));
  629. #endif
  630. }
  631.  
  632. bool MozQWidget::isVKBOpen()
  633. {
  634. return gKeyboardOpen;
  635. }
  636.  
  637. void
  638. MozQWidget::NotifyVKB(const QRect& rect)
  639. {
  640. QRegion region(scene()->views()[0]->rect());
  641. region -= rect;
  642. QRectF bounds = mapRectFromScene(region.boundingRect());
  643. nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
  644. if (observerService) {
  645. QString rect = QString("{\"left\": %1, \"top\": %2, \"right\": %3, \"bottom\": %4}")
  646. .arg(bounds.x()).arg(bounds.y()).arg(bounds.width()).arg(bounds.height());
  647. observerService->NotifyObservers(nsnull, "softkb-change", rect.utf16());
  648. }
  649. }
  650.  
  651. void MozQWidget::SwitchToForeground()
  652. {
  653. nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
  654. if (!os)
  655. return;
  656. os->NotifyObservers(nsnull, "application-foreground", nsnull);
  657. }
  658.  
  659. void MozQWidget::SwitchToBackground()
  660. {
  661. nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
  662. if (!os)
  663. return;
  664. os->NotifyObservers(nsnull, "application-background", nsnull);
  665. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement