MythTV  master
mythmainwindow.cpp
Go to the documentation of this file.
1 #include "mythmainwindow.h"
3 
4 // C headers
5 #include <cmath>
6 
7 // C++ headers
8 #include <algorithm>
9 #include <chrono>
10 #include <utility>
11 #include <vector>
12 
13 // QT
14 #include <QWaitCondition>
15 #include <QApplication>
16 #include <QHash>
17 #include <QFile>
18 #include <QDir>
19 #include <QEvent>
20 #include <QKeyEvent>
21 #include <QKeySequence>
22 #include <QInputMethodEvent>
23 #include <QSize>
24 #include <QWindow>
25 
26 // Platform headers
27 #include "unistd.h"
28 
29 // libmythbase headers
30 #include "libmythbase/compat.h"
32 #include "libmythbase/mythdate.h"
33 #include "libmythbase/mythdb.h"
34 #include "libmythbase/mythdirs.h"
35 #include "libmythbase/mythevent.h"
37 #include "libmythbase/mythmedia.h"
39 
40 // libmythui headers
41 #include "myththemebase.h"
42 #include "mythudplistener.h"
43 #include "mythrender_base.h"
44 #include "mythuistatetracker.h"
45 #include "mythuiactions.h"
46 #include "mythrect.h"
47 #include "mythdisplay.h"
48 #include "mythscreentype.h"
49 #include "mythpainter.h"
50 #include "mythpainterwindow.h"
51 #include "mythgesture.h"
52 #include "mythuihelper.h"
53 #include "mythdialogbox.h"
54 #include "mythscreensaver.h"
56 
57 
58 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
59 #ifdef Q_OS_ANDROID
60 #include <QtAndroid>
61 #endif
62 #endif
63 
64 static constexpr std::chrono::milliseconds GESTURE_TIMEOUT { 1s };
65 static constexpr std::chrono::minutes STANDBY_TIMEOUT { 90min };
66 static constexpr std::chrono::milliseconds LONGPRESS_INTERVAL { 1s };
67 
68 #define LOC QString("MythMainWindow: ")
69 
70 static MythMainWindow *s_mainWin = nullptr;
71 static QMutex s_mainLock;
72 
81 {
82  if (s_mainWin)
83  return s_mainWin;
84 
85  QMutexLocker lock(&s_mainLock);
86 
87  if (!s_mainWin)
88  {
89  s_mainWin = new MythMainWindow(UseDB);
91  }
92 
93  return s_mainWin;
94 }
95 
97 {
98  if (gCoreContext)
99  gCoreContext->SetGUIObject(nullptr);
100  delete s_mainWin;
101  s_mainWin = nullptr;
102 }
103 
105 {
107 }
108 
110 {
111  return s_mainWin != nullptr;
112 }
113 
115 {
117 }
118 
120 {
122 }
123 
125 {
127  return nullptr;
129 }
130 
132 {
134 
135  // Switch to desired GUI resolution
136  if (m_display->UsingVideoModes())
137  m_display->SwitchToGUI(true);
138 
141 
143 
144  setObjectName("mainwindow");
145 
146  m_priv->m_allowInput = false;
147 
148  // This prevents database errors from RegisterKey() when there is no DB:
149  m_priv->m_useDB = UseDB;
150 
151  //Init();
152 
153  m_priv->m_exitingtomain = false;
154  m_priv->m_popwindows = true;
155  m_priv->m_exitMenuCallback = nullptr;
157  m_priv->m_mediaDeviceForCallback = nullptr;
158  m_priv->m_escapekey = Qt::Key_Escape;
159  m_priv->m_mainStack = nullptr;
160 
161  installEventFilter(this);
162 
164 
165  InitKeys();
166 
167  m_priv->m_gestureTimer = new QTimer(this);
169  m_priv->m_hideMouseTimer = new QTimer(this);
170  m_priv->m_hideMouseTimer->setSingleShot(true);
171  m_priv->m_hideMouseTimer->setInterval(3s);
173  m_priv->m_allowInput = true;
175  m_refreshTimer.setInterval(17ms);
176  m_refreshTimer.start();
177  setUpdatesEnabled(true);
178 
180  Qt::BlockingQueuedConnection);
182  Qt::BlockingQueuedConnection);
183 #ifdef Q_OS_ANDROID
184  connect(qApp, &QApplication::applicationStateChanged, this, &MythMainWindow::OnApplicationStateChange);
185 #endif
186 
187  // We need to listen for playback start/end events
188  gCoreContext->addListener(this);
189 
190  // Idle timer setup
191  m_idleTime =
192  gCoreContext->GetDurSetting<std::chrono::minutes>("FrontendIdleTimeout",
194  if (m_idleTime < 0min)
195  m_idleTime = 0min;
196  m_idleTimer.setInterval(m_idleTime);
198  if (m_idleTime > 0min)
199  m_idleTimer.start();
200 
202  if (m_screensaver)
203  {
207  }
208 }
209 
211 {
212  delete m_screensaver;
213 
214  if (gCoreContext != nullptr)
216 
218 
219  while (!m_priv->m_stackList.isEmpty())
220  {
221  MythScreenStack *stack = m_priv->m_stackList.back();
222  m_priv->m_stackList.pop_back();
223 
224  if (stack == m_priv->m_mainStack)
225  m_priv->m_mainStack = nullptr;
226 
227  delete stack;
228  }
229 
230  delete m_themeBase;
231 
232  for (auto iter = m_priv->m_keyContexts.begin();
233  iter != m_priv->m_keyContexts.end();
234  iter = m_priv->m_keyContexts.erase(iter))
235  {
236  KeyContext *context = *iter;
237  delete context;
238  }
239 
240  delete m_deviceHandler;
241  delete m_priv->m_nc;
242 
244 
245  // N.B. we always call this to ensure the desktop mode is restored
246  // in case the setting was changed
248  delete m_display;
249 
250  delete m_priv;
251 }
252 
254 {
255  return m_display;
256 }
257 
259 {
260  return m_painter;
261 }
262 
264 {
265  return m_priv->m_nc;
266 }
267 
269 {
270  return m_painterWin;
271 }
272 
274 {
275  if (m_painterWin)
276  {
277  m_painterWin->show();
278  m_painterWin->raise();
279  }
280 }
281 
283 {
284  if (m_painterWin)
285  {
286  m_painterWin->clearMask();
288  m_painterWin->hide();
289  }
290 }
291 
293 {
294  return m_painterWin->GetRenderDevice();
295 }
296 
298 {
299  m_priv->m_stackList.push_back(Stack);
300  if (Main)
301  m_priv->m_mainStack = Stack;
302 }
303 
305 {
306  MythScreenStack *stack = m_priv->m_stackList.back();
307  m_priv->m_stackList.pop_back();
308  if (stack == m_priv->m_mainStack)
309  m_priv->m_mainStack = nullptr;
310  delete stack;
311 }
312 
314 {
315  return m_priv->m_stackList.size();
316 }
317 
319 {
320  return m_priv->m_mainStack;
321 }
322 
323 MythScreenStack *MythMainWindow::GetStack(const QString& Stackname)
324 {
325  for (auto * widget : std::as_const(m_priv->m_stackList))
326  if (widget->objectName() == Stackname)
327  return widget;
328  return nullptr;
329 }
330 
332 {
333  if (Position >= 0 && Position < m_priv->m_stackList.size())
334  return m_priv->m_stackList.at(Position);
335  return nullptr;
336 }
337 
339 {
340  if (!(m_painterWin && updatesEnabled()))
341  return;
342 
343  bool redraw = false;
344 
345  if (!m_repaintRegion.isEmpty())
346  redraw = true;
347 
348  // The call to GetDrawOrder can apparently alter m_stackList.
349  // NOLINTNEXTLINE(modernize-loop-convert,readability-qualified-auto) // both, qt6
350  for (auto it = m_priv->m_stackList.begin(); it != m_priv->m_stackList.end(); ++it)
351  {
352  QVector<MythScreenType *> drawList;
353  (*it)->GetDrawOrder(drawList);
354 
355  for (auto *screen : std::as_const(drawList))
356  {
357  screen->Pulse();
358 
359  if (screen->NeedsRedraw())
360  {
361  QRegion topDirty = screen->GetDirtyArea();
362  screen->ResetNeedsRedraw();
363  m_repaintRegion = m_repaintRegion.united(topDirty);
364  redraw = true;
365  }
366  }
367  }
368 
369  if (redraw && !m_painterWin->RenderIsShared())
370  m_painterWin->update(m_repaintRegion);
371 
372  for (auto *widget : std::as_const(m_priv->m_stackList))
373  widget->ScheduleInitIfNeeded();
374 }
375 
377 {
378  if (!(m_painterWin && updatesEnabled()))
379  return;
380 
381  if (Event)
382  m_repaintRegion = m_repaintRegion.united(Event->region());
383 
384  if (!m_painter->SupportsClipping())
385  {
387  }
388  else
389  {
390  // Ensure that the region is not larger than the screen which
391  // can happen with bad themes
393 
394  // Check for any widgets that have been updated since we built
395  // the dirty region list in ::animate()
396  // The call to GetDrawOrder can apparently alter m_stackList.
397  // NOLINTNEXTLINE(modernize-loop-convert,readability-qualified-auto) // both, qt6
398  for (auto it = m_priv->m_stackList.begin(); it != m_priv->m_stackList.end(); ++it)
399  {
400  QVector<MythScreenType *> redrawList;
401  (*it)->GetDrawOrder(redrawList);
402 
403  for (const auto *screen : std::as_const(redrawList))
404  {
405  if (screen->NeedsRedraw())
406  {
407  for (const QRect& wrect: screen->GetDirtyArea())
408  {
409  bool foundThisRect = false;
410  for (const QRect& drect: m_repaintRegion)
411  {
412  // Can't use QRegion::contains because it only
413  // checks for overlap. QRect::contains checks
414  // if fully contained.
415  if (drect.contains(wrect))
416  {
417  foundThisRect = true;
418  break;
419  }
420  }
421 
422  if (!foundThisRect)
423  return;
424  }
425  }
426  }
427  }
428  }
429 
431  Draw();
432 
433  m_repaintRegion = QRegion();
434 }
435 
437 {
438  if (!Painter)
439  Painter = m_painter;
440  if (!Painter)
441  return;
442 
443  Painter->Begin(m_painterWin);
444 
445  if (!Painter->SupportsClipping())
446  m_repaintRegion = QRegion(m_uiScreenRect);
447 
448  for (const QRect& rect : m_repaintRegion)
449  {
450  if (rect.width() == 0 || rect.height() == 0)
451  continue;
452 
453  if (rect != m_uiScreenRect)
454  Painter->SetClipRect(rect);
455 
456  // The call to GetDrawOrder can apparently alter m_stackList.
457  // NOLINTNEXTLINE(modernize-loop-convert,readability-qualified-auto) // both, qt6
458  for (auto it = m_priv->m_stackList.begin(); it != m_priv->m_stackList.end(); ++it)
459  {
460  QVector<MythScreenType *> redrawList;
461  (*it)->GetDrawOrder(redrawList);
462  for (auto *screen : std::as_const(redrawList))
463  screen->Draw(Painter, 0, 0, 255, rect);
464  }
465  }
466 
467  Painter->End();
468  m_repaintRegion = QRegion();
469 }
470 
471 // virtual
472 QPaintEngine *MythMainWindow::paintEngine() const
473 {
474  return testAttribute(Qt::WA_PaintOnScreen) ? nullptr : QWidget::paintEngine();
475 }
476 
478 {
479  if (Event->spontaneous())
480  {
481  auto * key = new QKeyEvent(QEvent::KeyPress, m_priv->m_escapekey, Qt::NoModifier);
482  QCoreApplication::postEvent(this, key);
483  Event->ignore();
484  return;
485  }
486 
487  QWidget::closeEvent(Event);
488 }
489 
490 void MythMainWindow::GrabWindow(QImage& Image)
491 {
492  WId winid = 0;
493  auto * active = QApplication::activeWindow();
494  if (active)
495  {
496  winid = active->winId();
497  }
498  else
499  {
500  // According to the following we page, you "just pass 0 as the
501  // window id, indicating that we want to grab the entire screen".
502  //
503  // https://doc.qt.io/qt-5/qtwidgets-desktop-screenshot-example.html#screenshot-class-implementation
504  winid = 0;
505  }
506 
507  auto * display = GetMythMainWindow()->GetDisplay();
508  if (auto * screen = display->GetCurrentScreen(); screen)
509  {
510  QPixmap image = screen->grabWindow(winid);
511  Image = image.toImage();
512  }
513 }
514 
515 /* This is required to allow a screenshot to be requested by another thread
516  * other than the UI thread, and to wait for the screenshot before returning.
517  * It is used by mythweb for the remote access screenshots
518  */
519 void MythMainWindow::DoRemoteScreenShot(const QString& Filename, int Width, int Height)
520 {
521  // This will be running in the UI thread, as is required by QPixmap
522  QStringList args;
523  args << QString::number(Width);
524  args << QString::number(Height);
525  args << Filename;
527  QCoreApplication::sendEvent(this, &me);
528 }
529 
530 void MythMainWindow::RemoteScreenShot(QString Filename, int Width, int Height)
531 {
532  // This will be running in a non-UI thread and is used to trigger a
533  // function in the UI thread, and waits for completion of that handler
534  emit SignalRemoteScreenShot(std::move(Filename), Width, Height);
535 }
536 
537 bool MythMainWindow::SaveScreenShot(const QImage& Image, QString Filename)
538 {
539  if (Filename.isEmpty())
540  {
541  QString fpath = GetMythDB()->GetSetting("ScreenShotPath", "/tmp");
542  Filename = QString("%1/myth-screenshot-%2.png")
544  }
545 
546  QString extension = Filename.section('.', -1, -1);
547  if (extension == "jpg")
548  extension = "JPEG";
549  else
550  extension = "PNG";
551 
552  LOG(VB_GENERAL, LOG_INFO, QString("Saving screenshot to %1 (%2x%3)")
553  .arg(Filename).arg(Image.width()).arg(Image.height()));
554 
555  if (Image.save(Filename, extension.toLatin1(), 100))
556  {
557  LOG(VB_GENERAL, LOG_INFO, "MythMainWindow::screenShot succeeded");
558  return true;
559  }
560 
561  LOG(VB_GENERAL, LOG_INFO, "MythMainWindow::screenShot Failed!");
562  return false;
563 }
564 
565 bool MythMainWindow::ScreenShot(int Width, int Height, QString Filename)
566 {
567  QImage img;
568  GrabWindow(img);
569  if (Width <= 0)
570  Width = img.width();
571  if (Height <= 0)
572  Height = img.height();
573  img = img.scaled(Width, Height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
574  return SaveScreenShot(img, std::move(Filename));
575 }
576 
578 {
579  if (HasMythMainWindow())
581 }
582 
584 {
585  if (HasMythMainWindow())
587 }
588 
590 {
591  if (HasMythMainWindow())
593 }
594 
596 {
597  if (HasMythMainWindow())
598  {
599  MythMainWindow* window = GetMythMainWindow();
600  if (window->m_screensaver)
601  return window->m_screensaver->Asleep();
602  }
603  return false;
604 }
605 
607 {
608  if (HasMythMainWindow())
610  return false;
611 }
612 
614 {
615  if (!updatesEnabled() && (Event->type() == QEvent::UpdateRequest))
616  m_priv->m_pendingUpdate = true;
617 
618  if (Event->type() == QEvent::Show && !Event->spontaneous())
619  QCoreApplication::postEvent(this, new QEvent(MythEvent::kMythPostShowEventType));
620 
622  {
623  raise();
624  activateWindow();
625  return true;
626  }
627 
628  if ((Event->type() == QEvent::WindowActivate) || (Event->type() == QEvent::WindowDeactivate))
630 
631  return QWidget::event(Event);
632 }
633 
635 {
639  QApplication::setStyle("Windows");
640 }
641 
642 void MythMainWindow::Init(bool MayReInit)
643 {
644  LoadQtConfig();
645  m_display->SetWidget(nullptr);
646  m_priv->m_useDB = ! gCoreContext->GetDB()->SuppressDBMessages();
647 
648  if (!(MayReInit || m_priv->m_firstinit))
649  return;
650 
651  // Set window border based on fullscreen attribute
652  Qt::WindowFlags flags = Qt::Window;
653 
655  bool inwindow = m_wantWindow && !m_qtFullScreen;
656  bool fullscreen = m_wantFullScreen && !GeometryIsOverridden();
657 
658  // On Compiz/Unit, when the window is fullscreen and frameless changing
659  // screen position ends up stuck. Adding a border temporarily prevents this
660  setWindowFlags(windowFlags() & ~Qt::FramelessWindowHint);
661 
662  if (!inwindow)
663  {
664  LOG(VB_GENERAL, LOG_INFO, "Using Frameless Window");
665  flags |= Qt::FramelessWindowHint;
666  }
667 
668  // Workaround Qt/Windows playback bug?
669 #ifdef _WIN32
670  flags |= Qt::MSWindowsOwnDC;
671 #endif
672 
673  // NOTE if running fullscreen AND windowed (i.e. borders etc) then we do not
674  // have any idea at this time of the size of the borders/decorations.
675  // Typically, on linux, this means we create the UI slightly larger than
676  // required - as X adds the decorations at a later point.
677 
678  if (fullscreen && !inwindow)
679  {
680  LOG(VB_GENERAL, LOG_INFO, "Using Full Screen Window");
681  if (m_priv->m_firstinit)
682  {
683  // During initialization, we force being fullscreen using setWindowState
684  // otherwise, in ubuntu's unity, the side bar often stays visible
685  setWindowState(Qt::WindowFullScreen);
686  }
687  }
688  else
689  {
690  // reset type
691  setWindowState(Qt::WindowNoState);
692  }
693 
695  flags |= Qt::WindowStaysOnTopHint;
696 
697  setWindowFlags(flags);
698 
699  // SetWidget may move the widget into a new screen.
700  m_display->SetWidget(this);
701  QTimer::singleShot(1s, this, &MythMainWindow::DelayedAction);
702 
703  // Ensure we have latest screen bounds if we have moved
705  SetUIScreenRect({{0, 0}, m_screenRect.size()});
707  Show();
708 
709  // The window is sometimes not created until Show has been called - so try
710  // MythDisplay::setWidget again to ensure we listen for QScreen changes
711  m_display->SetWidget(this);
712 
713  if (!GetMythDB()->GetBoolSetting("HideMouseCursor", false))
714  setMouseTracking(true); // Required for mouse cursor auto-hide
715  // Set cursor call must come after Show() to work on some systems.
716  ShowMouseCursor(false);
717 
718  move(m_screenRect.topLeft());
719 
720  if (m_painterWin || m_painter)
721  {
722  LOG(VB_GENERAL, LOG_INFO, "Destroying painter and painter window");
724  }
725 
726  QString warningmsg = MythPainterWindow::CreatePainters(this, m_painterWin, m_painter);
727  if (!warningmsg.isEmpty())
728  {
729  LOG(VB_GENERAL, LOG_WARNING, warningmsg);
730  }
731 
732  if (!m_painterWin)
733  {
734  LOG(VB_GENERAL, LOG_ERR, "MythMainWindow failed to create a painter window.");
735  return;
736  }
737 
738  if (m_painter && m_painter->GetName() != "Qt")
739  {
740  setAttribute(Qt::WA_NoSystemBackground);
741  setAutoFillBackground(false);
742  }
743  setAttribute(Qt::WA_InputMethodEnabled);
744 
747 
748  // Redraw the window now to avoid race conditions in EGLFS (Qt5.4) if a
749  // 2nd window (e.g. TVPlayback) is created before this is redrawn.
750 #ifdef Q_OS_ANDROID
751  static const QLatin1String EARLY_SHOW_PLATFORM_NAME_CHECK { "android" };
752 #else
753  static const QLatin1String EARLY_SHOW_PLATFORM_NAME_CHECK { "egl" };
754 #endif
755  if (QGuiApplication::platformName().contains(EARLY_SHOW_PLATFORM_NAME_CHECK))
756  QCoreApplication::processEvents();
757 
758  if (!GetMythDB()->GetBoolSetting("HideMouseCursor", false))
759  m_painterWin->setMouseTracking(true); // Required for mouse cursor auto-hide
760 
762  if (m_themeBase)
763  m_themeBase->Reload();
764  else
765  m_themeBase = new MythThemeBase(this);
766 
767  if (!m_priv->m_nc)
769 
770  emit SignalWindowReady();
771 
772  if (!warningmsg.isEmpty())
773  {
774  MythNotification notification(warningmsg, "");
775  m_priv->m_nc->Queue(notification);
776  }
777 }
778 
780 {
782  Show();
783 
784 #ifdef Q_OS_ANDROID
785 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
786  QtAndroid::hideSplashScreen();
787 #else
788  QNativeInterface::QAndroidApplication::hideSplashScreen();
789 #endif
790 #endif
791 }
792 
794 {
795  RegisterKey("Global", ACTION_UP, QT_TRANSLATE_NOOP("MythControls",
796  "Up Arrow"), "Up");
797  RegisterKey("Global", ACTION_DOWN, QT_TRANSLATE_NOOP("MythControls",
798  "Down Arrow"), "Down");
799  RegisterKey("Global", ACTION_LEFT, QT_TRANSLATE_NOOP("MythControls",
800  "Left Arrow"), "Left");
801  RegisterKey("Global", ACTION_RIGHT, QT_TRANSLATE_NOOP("MythControls",
802  "Right Arrow"), "Right");
803  RegisterKey("Global", "NEXT", QT_TRANSLATE_NOOP("MythControls",
804  "Move to next widget"), "Tab");
805  RegisterKey("Global", "PREVIOUS", QT_TRANSLATE_NOOP("MythControls",
806  "Move to preview widget"), "Backtab");
807  RegisterKey("Global", ACTION_SELECT, QT_TRANSLATE_NOOP("MythControls",
808  "Select"), "Return,Enter,Space");
809  RegisterKey("Global", "BACKSPACE", QT_TRANSLATE_NOOP("MythControls",
810  "Backspace"), "Backspace");
811  RegisterKey("Global", "ESCAPE", QT_TRANSLATE_NOOP("MythControls",
812  "Escape"), "Esc");
813  RegisterKey("Global", "MENU", QT_TRANSLATE_NOOP("MythControls",
814  "Pop-up menu"), "M,Meta+Enter");
815  RegisterKey("Global", "INFO", QT_TRANSLATE_NOOP("MythControls",
816  "More information"), "I");
817  RegisterKey("Global", "DELETE", QT_TRANSLATE_NOOP("MythControls",
818  "Delete"), "D");
819  RegisterKey("Global", "EDIT", QT_TRANSLATE_NOOP("MythControls",
820  "Edit"), "E");
821  RegisterKey("Global", ACTION_SCREENSHOT, QT_TRANSLATE_NOOP("MythControls",
822  "Save screenshot"), "");
823  RegisterKey("Global", ACTION_HANDLEMEDIA, QT_TRANSLATE_NOOP("MythControls",
824  "Play a media resource"), "");
825 
826  RegisterKey("Global", "PAGEUP", QT_TRANSLATE_NOOP("MythControls",
827  "Page Up"), "PgUp");
828  RegisterKey("Global", "PAGEDOWN", QT_TRANSLATE_NOOP("MythControls",
829  "Page Down"), "PgDown");
830  RegisterKey("Global", "PAGETOP", QT_TRANSLATE_NOOP("MythControls",
831  "Page to top of list"), "");
832  RegisterKey("Global", "PAGEMIDDLE", QT_TRANSLATE_NOOP("MythControls",
833  "Page to middle of list"), "");
834  RegisterKey("Global", "PAGEBOTTOM", QT_TRANSLATE_NOOP("MythControls",
835  "Page to bottom of list"), "");
836 
837  RegisterKey("Global", "PREVVIEW", QT_TRANSLATE_NOOP("MythControls",
838  "Previous View"), "Home");
839  RegisterKey("Global", "NEXTVIEW", QT_TRANSLATE_NOOP("MythControls",
840  "Next View"), "End");
841 
842  RegisterKey("Global", "HELP", QT_TRANSLATE_NOOP("MythControls",
843  "Help"), "F1");
844  RegisterKey("Global", "EJECT", QT_TRANSLATE_NOOP("MythControls"
845  ,"Eject Removable Media"), "");
846 
847  RegisterKey("Global", "CUT", QT_TRANSLATE_NOOP("MythControls",
848  "Cut text from textedit"), "Ctrl+X");
849  RegisterKey("Global", "COPY", QT_TRANSLATE_NOOP("MythControls"
850  ,"Copy text from textedit"), "Ctrl+C");
851  RegisterKey("Global", "PASTE", QT_TRANSLATE_NOOP("MythControls",
852  "Paste text into textedit"), "Ctrl+V");
853  RegisterKey("Global", "NEWLINE", QT_TRANSLATE_NOOP("MythControls",
854  "Insert newline into textedit"), "Ctrl+Return");
855  RegisterKey("Global", "UNDO", QT_TRANSLATE_NOOP("MythControls",
856  "Undo"), "Ctrl+Z");
857  RegisterKey("Global", "REDO", QT_TRANSLATE_NOOP("MythControls",
858  "Redo"), "Ctrl+Y");
859  RegisterKey("Global", "SEARCH", QT_TRANSLATE_NOOP("MythControls",
860  "Show incremental search dialog"), "Ctrl+S");
861 
862  RegisterKey("Global", ACTION_0, QT_TRANSLATE_NOOP("MythControls","0"), "0");
863  RegisterKey("Global", ACTION_1, QT_TRANSLATE_NOOP("MythControls","1"), "1");
864  RegisterKey("Global", ACTION_2, QT_TRANSLATE_NOOP("MythControls","2"), "2");
865  RegisterKey("Global", ACTION_3, QT_TRANSLATE_NOOP("MythControls","3"), "3");
866  RegisterKey("Global", ACTION_4, QT_TRANSLATE_NOOP("MythControls","4"), "4");
867  RegisterKey("Global", ACTION_5, QT_TRANSLATE_NOOP("MythControls","5"), "5");
868  RegisterKey("Global", ACTION_6, QT_TRANSLATE_NOOP("MythControls","6"), "6");
869  RegisterKey("Global", ACTION_7, QT_TRANSLATE_NOOP("MythControls","7"), "7");
870  RegisterKey("Global", ACTION_8, QT_TRANSLATE_NOOP("MythControls","8"), "8");
871  RegisterKey("Global", ACTION_9, QT_TRANSLATE_NOOP("MythControls","9"), "9");
872 
873  RegisterKey("Global", ACTION_TVPOWERON, QT_TRANSLATE_NOOP("MythControls",
874  "Turn the display on"), "");
875  RegisterKey("Global", ACTION_TVPOWEROFF, QT_TRANSLATE_NOOP("MythControls",
876  "Turn the display off"), "");
877 
878  RegisterKey("Global", "SYSEVENT01", QT_TRANSLATE_NOOP("MythControls",
879  "Trigger System Key Event #1"), "");
880  RegisterKey("Global", "SYSEVENT02", QT_TRANSLATE_NOOP("MythControls",
881  "Trigger System Key Event #2"), "");
882  RegisterKey("Global", "SYSEVENT03", QT_TRANSLATE_NOOP("MythControls",
883  "Trigger System Key Event #3"), "");
884  RegisterKey("Global", "SYSEVENT04", QT_TRANSLATE_NOOP("MythControls",
885  "Trigger System Key Event #4"), "");
886  RegisterKey("Global", "SYSEVENT05", QT_TRANSLATE_NOOP("MythControls",
887  "Trigger System Key Event #5"), "");
888  RegisterKey("Global", "SYSEVENT06", QT_TRANSLATE_NOOP("MythControls",
889  "Trigger System Key Event #6"), "");
890  RegisterKey("Global", "SYSEVENT07", QT_TRANSLATE_NOOP("MythControls",
891  "Trigger System Key Event #7"), "");
892  RegisterKey("Global", "SYSEVENT08", QT_TRANSLATE_NOOP("MythControls",
893  "Trigger System Key Event #8"), "");
894  RegisterKey("Global", "SYSEVENT09", QT_TRANSLATE_NOOP("MythControls",
895  "Trigger System Key Event #9"), "");
896  RegisterKey("Global", "SYSEVENT10", QT_TRANSLATE_NOOP("MythControls",
897  "Trigger System Key Event #10"), "");
898 
899  // these are for the html viewer widget (MythUIWebBrowser)
900  RegisterKey("Browser", "ZOOMIN", QT_TRANSLATE_NOOP("MythControls",
901  "Zoom in on browser window"), ".,>");
902  RegisterKey("Browser", "ZOOMOUT", QT_TRANSLATE_NOOP("MythControls",
903  "Zoom out on browser window"), ",,<");
904  RegisterKey("Browser", "TOGGLEINPUT", QT_TRANSLATE_NOOP("MythControls",
905  "Toggle where keyboard input goes to"), "F1");
906 
907  RegisterKey("Browser", "MOUSEUP", QT_TRANSLATE_NOOP("MythControls",
908  "Move mouse pointer up"), "2");
909  RegisterKey("Browser", "MOUSEDOWN", QT_TRANSLATE_NOOP("MythControls",
910  "Move mouse pointer down"), "8");
911  RegisterKey("Browser", "MOUSELEFT", QT_TRANSLATE_NOOP("MythControls",
912  "Move mouse pointer left"), "4");
913  RegisterKey("Browser", "MOUSERIGHT", QT_TRANSLATE_NOOP("MythControls",
914  "Move mouse pointer right"), "6");
915  RegisterKey("Browser", "MOUSELEFTBUTTON", QT_TRANSLATE_NOOP("MythControls",
916  "Mouse Left button click"), "5");
917 
918  RegisterKey("Browser", "PAGEDOWN", QT_TRANSLATE_NOOP("MythControls",
919  "Scroll down half a page"), "9");
920  RegisterKey("Browser", "PAGEUP", QT_TRANSLATE_NOOP("MythControls",
921  "Scroll up half a page"), "3");
922  RegisterKey("Browser", "PAGELEFT", QT_TRANSLATE_NOOP("MythControls",
923  "Scroll left half a page"), "7");
924  RegisterKey("Browser", "PAGERIGHT", QT_TRANSLATE_NOOP("MythControls",
925  "Scroll right half a page"), "1");
926 
927  RegisterKey("Browser", "NEXTLINK", QT_TRANSLATE_NOOP("MythControls",
928  "Move selection to next link"), "Z");
929  RegisterKey("Browser", "PREVIOUSLINK", QT_TRANSLATE_NOOP("MythControls",
930  "Move selection to previous link"), "Q");
931  RegisterKey("Browser", "FOLLOWLINK", QT_TRANSLATE_NOOP("MythControls",
932  "Follow selected link"), "Return,Space,Enter");
933  RegisterKey("Browser", "HISTORYBACK", QT_TRANSLATE_NOOP("MythControls",
934  "Go back to previous page"), "R,Backspace");
935  RegisterKey("Browser", "HISTORYFORWARD", QT_TRANSLATE_NOOP("MythControls",
936  "Go forward to previous page"), "F");
937 
938  RegisterKey("Main Menu", "EXITPROMPT", QT_TRANSLATE_NOOP("MythControls",
939  "Display System Exit Prompt"), "Esc");
940  RegisterKey("Main Menu", "EXIT", QT_TRANSLATE_NOOP("MythControls",
941  "System Exit"), "");
942  RegisterKey("Main Menu", "STANDBYMODE",QT_TRANSLATE_NOOP("MythControls",
943  "Enter Standby Mode"), "");
944  RegisterKey("Long Press", "LONGPRESS1",QT_TRANSLATE_NOOP("MythControls",
945  "Up to 16 Keys that allow Long Press"), "");
946  RegisterKey("Long Press", "LONGPRESS2",QT_TRANSLATE_NOOP("MythControls",
947  "Up to 16 Keys that allow Long Press"), "");
948  RegisterKey("Long Press", "LONGPRESS3",QT_TRANSLATE_NOOP("MythControls",
949  "Up to 16 Keys that allow Long Press"), "");
950  RegisterKey("Long Press", "LONGPRESS4",QT_TRANSLATE_NOOP("MythControls",
951  "Up to 16 Keys that allow Long Press"), "");
952 }
953 
955 {
956  ClearKeyContext("Global");
957  ClearKeyContext("Browser");
958  ClearKeyContext("Main Menu");
959  InitKeys();
960 }
961 
963 {
964  bool inwindow = m_wantWindow && !m_qtFullScreen;
965  bool fullscreen = m_wantFullScreen && !GeometryIsOverridden();
966  if (fullscreen && !inwindow && !m_priv->m_firstinit)
967  showFullScreen();
968  else
969  show();
970  m_priv->m_firstinit = false;
971 }
972 
973 void MythMainWindow::MoveResize(QRect& Geometry)
974 {
975  setFixedSize(Geometry.size());
976  setGeometry(Geometry);
977  if (m_painterWin)
978  {
979  m_painterWin->setFixedSize(Geometry.size());
980  m_painterWin->setGeometry(0, 0, Geometry.width(), Geometry.height());
981  }
982 }
983 
985 {
986  QMutexLocker locker(&m_priv->m_drawDisableLock);
988  if (m_priv->m_drawDisabledDepth && updatesEnabled())
989  SetDrawEnabled(false);
990  return m_priv->m_drawDisabledDepth;
991 }
992 
994 {
995  QMutexLocker locker(&m_priv->m_drawDisableLock);
997  {
999  if (!m_priv->m_drawDisabledDepth && !updatesEnabled())
1000  SetDrawEnabled(true);
1001  }
1002  return m_priv->m_drawDisabledDepth;
1003 }
1004 
1006 {
1007  if (!gCoreContext->IsUIThread())
1008  {
1009  emit SignalSetDrawEnabled(Enable);
1010  return;
1011  }
1012 
1013  setUpdatesEnabled(Enable);
1014  if (Enable)
1015  {
1016  if (m_priv->m_pendingUpdate)
1017  {
1018  QApplication::postEvent(this, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
1019  m_priv->m_pendingUpdate = false;
1020  }
1022  }
1023  else
1024  {
1026  }
1027 }
1028 
1030 {
1031  for (auto *widget : std::as_const(m_priv->m_stackList))
1032  {
1033  if (Enable)
1034  widget->EnableEffects();
1035  else
1036  widget->DisableEffects();
1037  }
1038 }
1039 
1041 {
1042  return m_priv->m_exitingtomain;
1043 }
1044 
1046 {
1047  bool jumpdone = !(m_priv->m_popwindows);
1048 
1049  m_priv->m_exitingtomain = true;
1050 
1051  MythScreenStack *toplevel = GetMainStack();
1052  if (toplevel && m_priv->m_popwindows)
1053  {
1054  MythScreenType *screen = toplevel->GetTopScreen();
1055  if (screen && screen->objectName() != QString("mainmenu"))
1056  {
1057  MythEvent xe("EXIT_TO_MENU");
1058  gCoreContext->dispatch(xe);
1059  if (screen->objectName() == QString("video playback window"))
1060  {
1061  auto *me = new MythEvent("EXIT_TO_MENU");
1062  QCoreApplication::postEvent(screen, me);
1063  }
1064  else
1065  {
1066  auto *key = new QKeyEvent(QEvent::KeyPress, m_priv->m_escapekey,
1067  Qt::NoModifier);
1068  QCoreApplication::postEvent(this, key);
1070  // Notifications have their own stack. We need to continue
1071  // the propagation of the escape here if there are notifications.
1072  int num = nc->DisplayedNotifications();
1073  if (num > 0)
1074  QCoreApplication::postEvent(
1075  this, new QEvent(MythEvent::kExitToMainMenuEventType));
1076  }
1077  return;
1078  }
1079  jumpdone = true;
1080  }
1081 
1082  if (jumpdone)
1083  {
1084  m_priv->m_exitingtomain = false;
1085  m_priv->m_popwindows = true;
1087  {
1088  void (*callback)(void) = m_priv->m_exitMenuCallback;
1089  m_priv->m_exitMenuCallback = nullptr;
1090  callback();
1091  }
1093  {
1096  m_priv->m_mediaDeviceForCallback = nullptr;
1097  callback(mediadevice);
1098  }
1099  }
1100 }
1101 
1112 bool MythMainWindow::TranslateKeyPress(const QString& Context, QKeyEvent* Event,
1113  QStringList& Actions, bool AllowJumps)
1114 {
1115  Actions.clear();
1116 
1117  // Special case for custom QKeyEvent where the action is embedded directly
1118  // in the QKeyEvent text property. Used by MythFEXML http extension
1119  if (Event && Event->key() == 0 &&
1120  !Event->text().isEmpty() &&
1121  Event->modifiers() == Qt::NoModifier)
1122  {
1123  QString action = Event->text();
1124  // check if it is a jumppoint
1125  if (!m_priv->m_destinationMap.contains(action))
1126  {
1127  Actions.append(action);
1128  return false;
1129  }
1130 
1131  if (AllowJumps)
1132  {
1133  // This does not filter the jump based on the current location but
1134  // is consistent with handling of other actions that do not need
1135  // a keybinding. The network control code tries to match
1136  // GetCurrentLocation with the jumppoint but matching is utterly
1137  // inconsistent e.g. mainmenu<->Main Menu, Playback<->Live TV
1138  JumpTo(action);
1139  return true;
1140  }
1141 
1142  return false;
1143  }
1144 
1146 
1147  QStringList localActions;
1148  auto * keycontext = m_priv->m_keyContexts.value(Context);
1149  if (AllowJumps && (m_priv->m_jumpMap.count(keynum) > 0) &&
1150  (!m_priv->m_jumpMap[keynum]->m_localAction.isEmpty()) &&
1151  keycontext && (keycontext->GetMapping(keynum, localActions)))
1152  {
1153  if (localActions.contains(m_priv->m_jumpMap[keynum]->m_localAction))
1154  AllowJumps = false;
1155  }
1156 
1157  if (AllowJumps && m_priv->m_jumpMap.count(keynum) > 0 &&
1158  !m_priv->m_jumpMap[keynum]->m_exittomain && m_priv->m_exitMenuCallback == nullptr)
1159  {
1160  void (*callback)(void) = m_priv->m_jumpMap[keynum]->m_callback;
1161  callback();
1162  return true;
1163  }
1164 
1165  if (AllowJumps &&
1166  m_priv->m_jumpMap.count(keynum) > 0 && m_priv->m_exitMenuCallback == nullptr)
1167  {
1168  m_priv->m_exitingtomain = true;
1169  m_priv->m_exitMenuCallback = m_priv->m_jumpMap[keynum]->m_callback;
1170  QCoreApplication::postEvent(
1171  this, new QEvent(MythEvent::kExitToMainMenuEventType));
1172  return true;
1173  }
1174 
1175  if (keycontext)
1176  keycontext->GetMapping(keynum, Actions);
1177 
1178  if (Context != "Global")
1179  {
1180  auto * keycontextG = m_priv->m_keyContexts.value("Global");
1181  if (keycontextG)
1182  keycontextG->GetMapping(keynum, Actions);
1183  }
1184 
1185  return false;
1186 }
1187 
1188 void MythMainWindow::ClearKey(const QString& Context, const QString& Action)
1189 {
1190  auto * keycontext = m_priv->m_keyContexts.value(Context);
1191  if (keycontext == nullptr)
1192  return;
1193 
1194  QMutableMapIterator<int, QStringList> it(keycontext->m_actionMap);
1195  while (it.hasNext())
1196  {
1197  it.next();
1198  QStringList list = it.value();
1199  list.removeAll(Action);
1200  if (list.isEmpty())
1201  it.remove();
1202  }
1203 }
1204 
1205 void MythMainWindow::ClearKeyContext(const QString& Context)
1206 {
1207  auto * keycontext = m_priv->m_keyContexts.value(Context);
1208  if (keycontext != nullptr)
1209  keycontext->m_actionMap.clear();
1210 }
1211 
1212 void MythMainWindow::BindKey(const QString& Context, const QString& Action, const QString& Key)
1213 {
1214  auto * keycontext = m_priv->m_keyContexts.value(Context);
1215  if (keycontext == nullptr)
1216  {
1217  keycontext = new KeyContext();
1218  if (keycontext == nullptr)
1219  return;
1220  m_priv->m_keyContexts.insert(Context, keycontext);
1221  }
1222 
1223  QKeySequence keyseq(Key);
1224  for (unsigned int i = 0; i < static_cast<uint>(keyseq.count()); i++)
1225  {
1226 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1227  int keynum = keyseq[i];
1228 #else
1229  int keynum = keyseq[i].toCombined();
1230 #endif
1231 
1232  QStringList dummyaction("");
1233  if (keycontext->GetMapping(keynum, dummyaction))
1234  {
1235  LOG(VB_GENERAL, LOG_WARNING, QString("Key %1 is bound to multiple actions in context %2.")
1236  .arg(Key, Context));
1237  }
1238 
1239  keycontext->AddMapping(keynum, Action);
1240 #if 0
1241  LOG(VB_GENERAL, LOG_DEBUG, QString("Binding: %1 to action: %2 (%3)")
1242  .arg(Key).arg(Action).arg(Context));
1243 #endif
1244 
1245  if (Action == "ESCAPE" && Context == "Global" && i == 0)
1246  m_priv->m_escapekey = keynum;
1247  }
1248 }
1249 
1250 void MythMainWindow::RegisterKey(const QString& Context, const QString& Action,
1251  const QString& Description, const QString& Key)
1252 {
1253  QString keybind = Key;
1254 
1255  MSqlQuery query(MSqlQuery::InitCon());
1256 
1257  if (m_priv->m_useDB && query.isConnected())
1258  {
1259  query.prepare("SELECT keylist, description FROM keybindings WHERE "
1260  "context = :CONTEXT AND action = :ACTION AND "
1261  "hostname = :HOSTNAME ;");
1262  query.bindValue(":CONTEXT", Context);
1263  query.bindValue(":ACTION", Action);
1264  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1265 
1266  if (query.exec() && query.next())
1267  {
1268  keybind = query.value(0).toString();
1269  QString db_description = query.value(1).toString();
1270 
1271  // Update keybinding description if changed
1272  if (db_description != Description)
1273  {
1274  LOG(VB_GENERAL, LOG_NOTICE,
1275  "Updating keybinding description...");
1276  query.prepare(
1277  "UPDATE keybindings "
1278  "SET description = :DESCRIPTION "
1279  "WHERE context = :CONTEXT AND "
1280  " action = :ACTION AND "
1281  " hostname = :HOSTNAME");
1282 
1283  query.bindValue(":DESCRIPTION", Description);
1284  query.bindValue(":CONTEXT", Context);
1285  query.bindValue(":ACTION", Action);
1286  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1287 
1288  if (!query.exec() && !(GetMythDB()->SuppressDBMessages()))
1289  {
1290  MythDB::DBError("Update Keybinding", query);
1291  }
1292  }
1293  }
1294  else
1295  {
1296  const QString& inskey = keybind;
1297 
1298  query.prepare("INSERT INTO keybindings (context, action, "
1299  "description, keylist, hostname) VALUES "
1300  "( :CONTEXT, :ACTION, :DESCRIPTION, :KEYLIST, "
1301  ":HOSTNAME );");
1302  query.bindValue(":CONTEXT", Context);
1303  query.bindValue(":ACTION", Action);
1304  query.bindValue(":DESCRIPTION", Description);
1305  query.bindValue(":KEYLIST", inskey);
1306  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1307 
1308  if (!query.exec() && !(GetMythDB()->SuppressDBMessages()))
1309  {
1310  MythDB::DBError("Insert Keybinding", query);
1311  }
1312  }
1313  }
1314 
1315  BindKey(Context, Action, keybind);
1316  m_priv->m_actionText[Context][Action] = Description;
1317 }
1318 
1319 QString MythMainWindow::GetKey(const QString& Context, const QString& Action)
1320 {
1321  MSqlQuery query(MSqlQuery::InitCon());
1322  if (!query.isConnected())
1323  return "?";
1324 
1325  query.prepare("SELECT keylist "
1326  "FROM keybindings "
1327  "WHERE context = :CONTEXT AND "
1328  " action = :ACTION AND "
1329  " hostname = :HOSTNAME");
1330  query.bindValue(":CONTEXT", Context);
1331  query.bindValue(":ACTION", Action);
1332  query.bindValue(":HOSTNAME", GetMythDB()->GetHostName());
1333 
1334  if (!query.exec() || !query.isActive() || !query.next())
1335  return "?";
1336 
1337  return query.value(0).toString();
1338 }
1339 
1340 QString MythMainWindow::GetActionText(const QString& Context,
1341  const QString& Action) const
1342 {
1343  if (m_priv->m_actionText.contains(Context))
1344  {
1345  QHash<QString, QString> entry = m_priv->m_actionText.value(Context);
1346  if (entry.contains(Action))
1347  return entry.value(Action);
1348  }
1349  return "";
1350 }
1351 
1352 void MythMainWindow::ClearJump(const QString& Destination)
1353 {
1354  // make sure that the jump point exists (using [] would add it)
1355  if (!m_priv->m_destinationMap.contains(Destination))
1356  {
1357  LOG(VB_GENERAL, LOG_ERR, "Cannot clear ficticious jump point" + Destination);
1358  return;
1359  }
1360 
1361  QMutableMapIterator<int, JumpData*> it(m_priv->m_jumpMap);
1362  while (it.hasNext())
1363  {
1364  it.next();
1365  JumpData *jd = it.value();
1366  if (jd->m_destination == Destination)
1367  it.remove();
1368  }
1369 }
1370 
1371 
1372 void MythMainWindow::BindJump(const QString& Destination, const QString& Key)
1373 {
1374  // make sure the jump point exists
1375  if (!m_priv->m_destinationMap.contains(Destination))
1376  {
1377  LOG(VB_GENERAL, LOG_ERR, "Cannot bind to ficticious jump point" + Destination);
1378  return;
1379  }
1380 
1381  QKeySequence keyseq(Key);
1382 
1383  for (unsigned int i = 0; i < static_cast<uint>(keyseq.count()); i++)
1384  {
1385 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1386  int keynum = keyseq[i];
1387 #else
1388  int keynum = keyseq[i].toCombined();
1389 #endif
1390 
1391  if (m_priv->m_jumpMap.count(keynum) == 0)
1392  {
1393 #if 0
1394  LOG(VB_GENERAL, LOG_DEBUG, QString("Binding: %1 to JumpPoint: %2")
1395  .arg(keybind).arg(destination));
1396 #endif
1397 
1398  m_priv->m_jumpMap[keynum] = &m_priv->m_destinationMap[Destination];
1399  }
1400  else
1401  {
1402  LOG(VB_GENERAL, LOG_WARNING, QString("Key %1 is already bound to a jump point.")
1403  .arg(Key));
1404  }
1405  }
1406 #if 0
1407  else
1408  LOG(VB_GENERAL, LOG_DEBUG,
1409  QString("JumpPoint: %2 exists, no keybinding") .arg(destination));
1410 #endif
1411 }
1412 
1413 void MythMainWindow::RegisterJump(const QString& Destination, const QString& Description,
1414  const QString& Key, void (*Callback)(void),
1415  bool Exittomain, QString LocalAction)
1416 {
1417  QString keybind = Key;
1418 
1419  MSqlQuery query(MSqlQuery::InitCon());
1420  if (query.isConnected())
1421  {
1422  query.prepare("SELECT keylist FROM jumppoints WHERE destination = :DEST and hostname = :HOST ;");
1423  query.bindValue(":DEST", Destination);
1424  query.bindValue(":HOST", GetMythDB()->GetHostName());
1425  if (query.exec() && query.next())
1426  {
1427  keybind = query.value(0).toString();
1428  }
1429  else
1430  {
1431  const QString& inskey = keybind;
1432 
1433  query.prepare("INSERT INTO jumppoints (destination, description, "
1434  "keylist, hostname) VALUES ( :DEST, :DESC, :KEYLIST, "
1435  ":HOST );");
1436  query.bindValue(":DEST", Destination);
1437  query.bindValue(":DESC", Description);
1438  query.bindValue(":KEYLIST", inskey);
1439  query.bindValue(":HOST", GetMythDB()->GetHostName());
1440  if (!query.exec() || !query.isActive())
1441  MythDB::DBError("Insert Jump Point", query);
1442  }
1443  }
1444 
1445  JumpData jd = { Callback, Destination, Description, Exittomain, std::move(LocalAction) };
1446  m_priv->m_destinationMap[Destination] = jd;
1447  BindJump(Destination, keybind);
1448 }
1449 
1451 {
1452  QList<QString> destinations = m_priv->m_destinationMap.keys();
1453  QList<QString>::Iterator it;
1454  for (it = destinations.begin(); it != destinations.end(); ++it)
1455  ClearJump(*it);
1456 }
1457 
1458 void MythMainWindow::JumpTo(const QString& Destination, bool Pop)
1459 {
1460  if (m_priv->m_destinationMap.count(Destination) > 0 && m_priv->m_exitMenuCallback == nullptr)
1461  {
1462  m_priv->m_exitingtomain = true;
1463  m_priv->m_popwindows = Pop;
1464  m_priv->m_exitMenuCallback = m_priv->m_destinationMap[Destination].m_callback;
1465  QCoreApplication::postEvent(
1466  this, new QEvent(MythEvent::kExitToMainMenuEventType));
1467  return;
1468  }
1469 }
1470 
1471 bool MythMainWindow::DestinationExists(const QString& Destination) const
1472 {
1473  return m_priv->m_destinationMap.count(Destination) > 0;
1474 }
1475 
1477 {
1478  return m_priv->m_destinationMap.keys();
1479 }
1480 
1481 void MythMainWindow::RegisterMediaPlugin(const QString& Name, const QString& Desc,
1482  MediaPlayCallback Func)
1483 {
1484  if (m_priv->m_mediaPluginMap.count(Name) == 0)
1485  {
1486  LOG(VB_GENERAL, LOG_NOTICE, QString("Registering %1 as a media playback plugin.")
1487  .arg(Name));
1488  m_priv->m_mediaPluginMap[Name] = { Desc, Func };
1489  }
1490  else
1491  {
1492  LOG(VB_GENERAL, LOG_NOTICE, QString("%1 is already registered as a media playback plugin.")
1493  .arg(Name));
1494  }
1495 }
1496 
1497 bool MythMainWindow::HandleMedia(const QString& Handler, const QString& Mrl,
1498  const QString& Plot, const QString& Title,
1499  const QString& Subtitle,
1500  const QString& Director, int Season,
1501  int Episode, const QString& Inetref,
1502  std::chrono::minutes LenMins, const QString& Year,
1503  const QString& Id, bool UseBookmarks)
1504 {
1505  QString lhandler(Handler);
1506  if (lhandler.isEmpty())
1507  lhandler = "Internal";
1508 
1509  // Let's see if we have a plugin that matches the handler name...
1510  if (m_priv->m_mediaPluginMap.contains(lhandler))
1511  {
1512  m_priv->m_mediaPluginMap[lhandler].second(Mrl, Plot, Title, Subtitle,
1513  Director, Season, Episode,
1514  Inetref, LenMins, Year, Id,
1515  UseBookmarks);
1516  return true;
1517  }
1518 
1519  return false;
1520 }
1521 
1523 {
1525 }
1526 
1528 {
1529  m_priv->m_allowInput = Allow;
1530 }
1531 
1533 {
1534  // complete the stroke if its our first timeout
1535  if (m_priv->m_gesture.Recording())
1536  m_priv->m_gesture.Stop(true);
1537 
1538  // get the last gesture
1539  auto * event = m_priv->m_gesture.GetGesture();
1540  if (event->GetGesture() < MythGestureEvent::Click)
1541  QCoreApplication::postEvent(this, event);
1542 }
1543 
1544 // Return code = true to skip further processing, false to continue
1545 // sNewEvent: Caller must pass in a QScopedPointer that will be used
1546 // to delete a new event if one is created.
1547 bool MythMainWindow::KeyLongPressFilter(QEvent** Event, QScopedPointer<QEvent>& NewEvent)
1548 {
1549  auto * keyevent = dynamic_cast<QKeyEvent*>(*Event);
1550  if (!keyevent)
1551  return false;
1552  int keycode = keyevent->key();
1553  // Ignore unknown key codes
1554  if (keycode == 0)
1555  return false;
1556 
1557  QEvent *newevent = nullptr;
1558  switch ((*Event)->type())
1559  {
1560  case QEvent::KeyPress:
1561  {
1562  // Check if we are in the middle of a long press
1563  if (keycode == m_priv->m_longPressKeyCode)
1564  {
1565  if (std::chrono::milliseconds(keyevent->timestamp()) - m_priv->m_longPressTime < LONGPRESS_INTERVAL
1566  || m_priv->m_longPressTime == 0ms)
1567  {
1568  // waiting for release of key.
1569  return true; // discard the key press
1570  }
1571 
1572  // expired log press - generate long key
1573  newevent = new QKeyEvent(QEvent::KeyPress, keycode,
1574  keyevent->modifiers() | Qt::MetaModifier, keyevent->nativeScanCode(),
1575  keyevent->nativeVirtualKey(), keyevent->nativeModifiers(),
1576  keyevent->text(), false,1);
1577  *Event = newevent;
1578  NewEvent.reset(newevent);
1579  m_priv->m_longPressTime = 0ms; // indicate we have generated the long press
1580  return false;
1581  }
1582  // If we got a keycode different from the long press keycode it
1583  // may have been injected by a jump point. Ignore it.
1584  if (m_priv->m_longPressKeyCode != 0)
1585  return false;
1586 
1587  // Process start of possible new long press.
1589  QStringList actions;
1590  bool handled = TranslateKeyPress("Long Press", keyevent, actions,false);
1591  if (handled)
1592  {
1593  // This shoudl never happen,, because we passed in false
1594  // to say do not process jump points and yet it returned true
1595  // to say it processed a jump point.
1596  LOG(VB_GUI, LOG_ERR, QString("TranslateKeyPress Long Press Invalid Response"));
1597  return true;
1598  }
1599  if (!actions.empty() && actions[0].startsWith("LONGPRESS"))
1600  {
1601  // Beginning of a press
1602  m_priv->m_longPressKeyCode = keycode;
1603  m_priv->m_longPressTime = std::chrono::milliseconds(keyevent->timestamp());
1604  return true; // discard the key press
1605  }
1606  break;
1607  }
1608  case QEvent::KeyRelease:
1609  {
1610  if (keycode == m_priv->m_longPressKeyCode)
1611  {
1612  if (keyevent->isAutoRepeat())
1613  return true;
1614  if (m_priv->m_longPressTime > 0ms)
1615  {
1616  // short press or non-repeating keyboard - generate key
1617  Qt::KeyboardModifiers modifier = Qt::NoModifier;
1618  if (std::chrono::milliseconds(keyevent->timestamp()) - m_priv->m_longPressTime >= LONGPRESS_INTERVAL)
1619  {
1620  // non-repeatng keyboard
1621  modifier = Qt::MetaModifier;
1622  }
1623  newevent = new QKeyEvent(QEvent::KeyPress, keycode,
1624  keyevent->modifiers() | modifier, keyevent->nativeScanCode(),
1625  keyevent->nativeVirtualKey(), keyevent->nativeModifiers(),
1626  keyevent->text(), false,1);
1627  *Event = newevent;
1628  NewEvent.reset(newevent);
1630  return false;
1631  }
1632 
1633  // end of long press
1635  return true;
1636  }
1637  break;
1638  }
1639  default:
1640  break;
1641  }
1642  return false;
1643 }
1644 
1645 bool MythMainWindow::eventFilter(QObject* Watched, QEvent* Event)
1646 {
1647  /* Don't let anything through if input is disallowed. */
1648  if (!m_priv->m_allowInput)
1649  return true;
1650 
1651  QScopedPointer<QEvent> newevent(nullptr);
1652  if (KeyLongPressFilter(&Event, newevent))
1653  return true;
1654 
1655  switch (Event->type())
1656  {
1657  case QEvent::KeyPress:
1658  {
1659  ResetIdleTimer();
1660  auto * event = dynamic_cast<QKeyEvent*>(Event);
1661 
1662  // Work around weird GCC run-time bug. Only manifest on Mac OS X
1663  if (!event)
1664  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
1665  event = static_cast<QKeyEvent*>(Event);
1666 
1667 #ifdef Q_OS_LINUX
1668  // Fixups for _some_ linux native codes that QT doesn't know
1669  if (event && event->key() <= 0)
1670  {
1671  int keycode = 0;
1672  switch (event->nativeScanCode())
1673  {
1674  case 209: // XF86AudioPause
1675  keycode = Qt::Key_MediaPause;
1676  break;
1677  default:
1678  break;
1679  }
1680 
1681  if (keycode > 0)
1682  {
1683  auto * key = new QKeyEvent(QEvent::KeyPress, keycode, event->modifiers());
1684  if (auto * target = GetTarget(*key); target)
1685  QCoreApplication::postEvent(target, key);
1686  else
1687  QCoreApplication::postEvent(this, key);
1688  return true;
1689  }
1690  }
1691 #endif
1692 
1693  QVector<MythScreenStack *>::const_reverse_iterator it;
1694  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1695  {
1696  if (auto * top = (*it)->GetTopScreen(); top)
1697  {
1698  if (top->keyPressEvent(event))
1699  return true;
1700  // Note: The following break prevents keypresses being
1701  // sent to windows below popups
1702  if ((*it)->objectName() == "popup stack")
1703  break;
1704  }
1705  }
1706  break;
1707  }
1708  case QEvent::InputMethod:
1709  {
1710  ResetIdleTimer();
1711  auto *ie = dynamic_cast<QInputMethodEvent*>(Event);
1712  if (!ie)
1713  return MythUIScreenBounds::eventFilter(Watched, Event);
1714  QWidget *widget = QApplication::focusWidget();
1715  if (widget)
1716  {
1717  ie->accept();
1718  if (widget->isEnabled())
1719  QCoreApplication::instance()->notify(widget, ie);
1720  break;
1721  }
1722  QVector<MythScreenStack *>::const_reverse_iterator it;
1723  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1724  {
1725  MythScreenType *top = (*it)->GetTopScreen();
1726  if (top == nullptr)
1727  continue;
1728  if (top->inputMethodEvent(ie))
1729  return true;
1730  // Note: The following break prevents keypresses being
1731  // sent to windows below popups
1732  if ((*it)->objectName() == "popup stack")
1733  break;
1734  }
1735  break;
1736  }
1737  case QEvent::MouseButtonPress:
1738  {
1739  ResetIdleTimer();
1740  ShowMouseCursor(true);
1741  if (!m_priv->m_gesture.Recording())
1742  {
1743  m_priv->m_gesture.Start();
1744  auto * mouseEvent = dynamic_cast<QMouseEvent*>(Event);
1745  if (!mouseEvent)
1746  return MythUIScreenBounds::eventFilter(Watched, Event);
1747  m_priv->m_gesture.Record(mouseEvent->pos(), mouseEvent->button());
1748  /* start a single shot timer */
1750  return true;
1751  }
1752  break;
1753  }
1754  case QEvent::MouseButtonRelease:
1755  {
1756  ResetIdleTimer();
1757  ShowMouseCursor(true);
1758  if (m_priv->m_gestureTimer->isActive())
1759  m_priv->m_gestureTimer->stop();
1760 
1761  if (m_priv->m_gesture.Recording())
1762  {
1763  m_priv->m_gesture.Stop();
1764  auto * gesture = m_priv->m_gesture.GetGesture();
1765  QPoint point { -1, -1 };
1766  auto * mouseevent = dynamic_cast<QMouseEvent*>(Event);
1767  if (mouseevent)
1768  {
1769  point = mouseevent->pos();
1770  gesture->SetPosition(point);
1771  }
1772 
1773  // Handle clicks separately
1774  if (gesture->GetGesture() == MythGestureEvent::Click)
1775  {
1776  if (!mouseevent)
1777  return MythUIScreenBounds::eventFilter(Watched, Event);
1778 
1779  QVector<MythScreenStack *>::const_reverse_iterator it;
1780  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1781  {
1782  auto * screen = (*it)->GetTopScreen();
1783  if (!screen || !screen->ContainsPoint(point))
1784  continue;
1785 
1786  if (screen->gestureEvent(gesture))
1787  break;
1788  // Note: The following break prevents clicks being
1789  // sent to windows below popups
1790  //
1791  // we want to permit this in some cases, e.g.
1792  // when the music miniplayer is on screen or a
1793  // non-interactive alert/news scroller. So these
1794  // things need to be in a third or more stack
1795  if ((*it)->objectName() == "popup stack")
1796  break;
1797  }
1798  delete gesture;
1799  }
1800  else
1801  {
1802  bool handled = false;
1803 
1804  if (!mouseevent)
1805  {
1806  QCoreApplication::postEvent(this, gesture);
1807  return true;
1808  }
1809 
1810  QVector<MythScreenStack *>::const_reverse_iterator it;
1811  for (it = m_priv->m_stackList.rbegin(); it != m_priv->m_stackList.rend(); it++)
1812  {
1813  MythScreenType *screen = (*it)->GetTopScreen();
1814  if (!screen || !screen->ContainsPoint(point))
1815  continue;
1816 
1817  if (screen->gestureEvent(gesture))
1818  {
1819  handled = true;
1820  break;
1821  }
1822  // Note: The following break prevents clicks being
1823  // sent to windows below popups
1824  //
1825  // we want to permit this in some cases, e.g.
1826  // when the music miniplayer is on screen or a
1827  // non-interactive alert/news scroller. So these
1828  // things need to be in a third or more stack
1829  if ((*it)->objectName() == "popup stack")
1830  break;
1831  }
1832 
1833  if (handled)
1834  delete gesture;
1835  else
1836  QCoreApplication::postEvent(this, gesture);
1837  }
1838 
1839  return true;
1840  }
1841  break;
1842  }
1843  case QEvent::MouseMove:
1844  {
1845  ResetIdleTimer();
1846  ShowMouseCursor(true);
1847  if (m_priv->m_gesture.Recording())
1848  {
1849  // Reset the timer
1850  m_priv->m_gestureTimer->stop();
1852  auto * mouseevent = dynamic_cast<QMouseEvent*>(Event);
1853  if (!mouseevent)
1854  return MythUIScreenBounds::eventFilter(Watched, Event);
1855  m_priv->m_gesture.Record(mouseevent->pos(), mouseevent->button());
1856  return true;
1857  }
1858  break;
1859  }
1860  case QEvent::Wheel:
1861  {
1862  ResetIdleTimer();
1863  ShowMouseCursor(true);
1864  auto * wheel = dynamic_cast<QWheelEvent*>(Event);
1865  if (wheel == nullptr)
1866  return MythUIScreenBounds::eventFilter(Watched, Event);
1867  int delta = wheel->angleDelta().y();
1868  if (delta>0)
1869  {
1870  wheel->accept();
1871  auto *key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier);
1872  if (auto * target = GetTarget(*key); target)
1873  QCoreApplication::postEvent(target, key);
1874  else
1875  QCoreApplication::postEvent(this, key);
1876  }
1877  if (delta < 0)
1878  {
1879  wheel->accept();
1880  auto * key = new QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier);
1881  if (auto * target = GetTarget(*key); !target)
1882  QCoreApplication::postEvent(target, key);
1883  else
1884  QCoreApplication::postEvent(this, key);
1885  }
1886  break;
1887  }
1888  default:
1889  break;
1890  }
1891 
1892  return MythUIScreenBounds::eventFilter(Watched, Event);
1893 }
1894 
1896 {
1897  if (Event->type() == MythGestureEvent::kEventType)
1898  {
1899  auto * gesture = dynamic_cast<MythGestureEvent*>(Event);
1900  if (gesture == nullptr)
1901  return;
1902  if (auto * toplevel = GetMainStack(); toplevel)
1903  if (auto * screen = toplevel->GetTopScreen(); screen)
1904  screen->gestureEvent(gesture);
1905  LOG(VB_GUI, LOG_DEBUG, QString("Gesture: %1 (Button: %2)")
1906  .arg(gesture->GetName(), gesture->GetButtonName()));
1907  }
1909  {
1910  ExitToMainMenu();
1911  }
1912  else if (Event->type() == ExternalKeycodeEvent::kEventType)
1913  {
1914  auto * event = dynamic_cast<ExternalKeycodeEvent *>(Event);
1915  if (event == nullptr)
1916  return;
1917  auto * key = new QKeyEvent(QEvent::KeyPress, event->getKeycode(), Qt::NoModifier);
1918  if (auto * target = GetTarget(*key); target)
1919  QCoreApplication::sendEvent(target, key);
1920  else
1921  QCoreApplication::sendEvent(this, key);
1922  }
1923  else if (Event->type() == MythMediaEvent::kEventType)
1924  {
1925  auto *me = dynamic_cast<MythMediaEvent*>(Event);
1926  if (me == nullptr)
1927  return;
1928 
1929  // A listener based system might be more efficient, but we should never
1930  // have that many screens open at once so impact should be minimal.
1931  //
1932  // This approach is simpler for everyone to follow. Plugin writers
1933  // don't have to worry about adding their screens to the list because
1934  // all screens receive media events.
1935  //
1936  // Events are even sent to hidden or backgrounded screens, this avoids
1937  // the need for those to poll for changes when they become visible again
1938  // however this needs to be kept in mind if media changes trigger
1939  // actions which would not be appropriate when the screen doesn't have
1940  // focus. It is the programmers responsibility to ignore events when
1941  // necessary.
1942  for (auto * widget : std::as_const(m_priv->m_stackList))
1943  {
1944  QVector<MythScreenType*> screenList;
1945  widget->GetScreenList(screenList);
1946  for (auto * screen : std::as_const(screenList))
1947  if (screen)
1948  screen->mediaEvent(me);
1949  }
1950 
1951  // Debugging
1952  if (MythMediaDevice* device = me->getDevice(); device)
1953  {
1954  LOG(VB_GENERAL, LOG_DEBUG, QString("Media Event: %1 - %2")
1955  .arg(device->getDevicePath()).arg(device->getStatus()));
1956  }
1957  }
1958  else if (Event->type() == MythEvent::kPushDisableDrawingEventType)
1959  {
1960  PushDrawDisabled();
1961  }
1962  else if (Event->type() == MythEvent::kPopDisableDrawingEventType)
1963  {
1964  PopDrawDisabled();
1965  }
1966  else if (Event->type() == MythEvent::kLockInputDevicesEventType)
1967  {
1968  m_deviceHandler->IgnoreKeys(true);
1969  PauseIdleTimer(true);
1970  }
1971  else if (Event->type() == MythEvent::kUnlockInputDevicesEventType)
1972  {
1973  m_deviceHandler->IgnoreKeys(false);
1974  PauseIdleTimer(false);
1975  }
1976  else if (Event->type() == MythEvent::kDisableUDPListenerEventType)
1977  {
1979  }
1980  else if (Event->type() == MythEvent::kEnableUDPListenerEventType)
1981  {
1983  }
1984  else if (Event->type() == MythEvent::kMythEventMessage)
1985  {
1986  auto * event = dynamic_cast<MythEvent *>(Event);
1987  if (event == nullptr)
1988  return;
1989 
1990  QString message = event->Message();
1991  if (message.startsWith(ACTION_HANDLEMEDIA))
1992  {
1993  if (event->ExtraDataCount() == 1)
1994  HandleMedia("Internal", event->ExtraData(0));
1995  else if (event->ExtraDataCount() >= 11)
1996  {
1997  bool usebookmark = true;
1998  if (event->ExtraDataCount() >= 12)
1999  usebookmark = (event->ExtraData(11).toInt() != 0);
2000  HandleMedia("Internal", event->ExtraData(0),
2001  event->ExtraData(1), event->ExtraData(2),
2002  event->ExtraData(3), event->ExtraData(4),
2003  event->ExtraData(5).toInt(), event->ExtraData(6).toInt(),
2004  event->ExtraData(7), std::chrono::minutes(event->ExtraData(8).toInt()),
2005  event->ExtraData(9), event->ExtraData(10),
2006  usebookmark);
2007  }
2008  else
2009  {
2010  LOG(VB_GENERAL, LOG_ERR, "Failed to handle media");
2011  }
2012  }
2013  else if (message.startsWith(ACTION_SCREENSHOT))
2014  {
2015  int width = 0;
2016  int height = 0;
2017  QString filename;
2018  if (event->ExtraDataCount() >= 2)
2019  {
2020  width = event->ExtraData(0).toInt();
2021  height = event->ExtraData(1).toInt();
2022  if (event->ExtraDataCount() == 3)
2023  filename = event->ExtraData(2);
2024  }
2025  ScreenShot(width, height, filename);
2026  }
2027  else if (message == ACTION_GETSTATUS)
2028  {
2029  QVariantMap state;
2030  state.insert("state", "idle");
2031  state.insert("menutheme", GetMythDB()->GetSetting("menutheme", "defaultmenu"));
2032  state.insert("currentlocation", GetMythUI()->GetCurrentLocation());
2034  }
2035  else if (message == "CLEAR_SETTINGS_CACHE")
2036  {
2037  // update the idle time
2038  m_idleTime =
2039  gCoreContext->GetDurSetting<std::chrono::minutes>("FrontendIdleTimeout",
2040  STANDBY_TIMEOUT);
2041 
2042  if (m_idleTime < 0min)
2043  m_idleTime = 0min;
2044  m_idleTimer.stop();
2045  if (m_idleTime > 0min)
2046  {
2047  m_idleTimer.setInterval(m_idleTime);
2048  m_idleTimer.start();
2049  LOG(VB_GENERAL, LOG_INFO, QString("Updating the frontend idle time to: %1 mins").arg(m_idleTime.count()));
2050  }
2051  else
2052  {
2053  LOG(VB_GENERAL, LOG_INFO, "Frontend idle timeout is disabled");
2054  }
2055  }
2056  else if (message == "NOTIFICATION")
2057  {
2058  MythNotification mn(*event);
2060  return;
2061  }
2062  else if (message == "RECONNECT_SUCCESS" && m_priv->m_standby)
2063  {
2064  // If the connection to the master backend has just been (re-)established
2065  // but we're in standby, make sure the backend is not blocked from
2066  // shutting down.
2068  }
2069  }
2070  else if (Event->type() == MythEvent::kMythUserMessage)
2071  {
2072  if (auto * event = dynamic_cast<MythEvent *>(Event); event != nullptr)
2073  if (const QString& message = event->Message(); !message.isEmpty())
2074  ShowOkPopup(message);
2075  }
2076  else if (Event->type() == MythNotificationCenterEvent::kEventType)
2077  {
2079  }
2080 }
2081 
2082 QObject* MythMainWindow::GetTarget(QKeyEvent& Key)
2083 {
2084  auto * target = QWidget::keyboardGrabber();
2085  if (!target)
2086  {
2087  if (auto * widget = QApplication::focusWidget(); widget && widget->isEnabled())
2088  {
2089  target = widget;
2090  // Yes this is special code for handling the
2091  // the escape key.
2092  if (Key.key() == m_priv->m_escapekey && widget->topLevelWidget())
2093  target = widget->topLevelWidget();
2094  }
2095  }
2096 
2097  if (!target)
2098  target = this;
2099  return target;
2100 }
2101 
2103 {
2105 }
2106 
2108 {
2109  if (Show && GetMythDB()->GetBoolSetting("HideMouseCursor", false))
2110  return;
2111 
2112  // Set cursor call must come after Show() to work on some systems.
2113  setCursor(Show ? (Qt::ArrowCursor) : (Qt::BlankCursor));
2114  if (Show)
2115  m_priv->m_hideMouseTimer->start();
2116 }
2117 
2119 {
2120  ShowMouseCursor(false);
2121 }
2122 
2126 void MythMainWindow::DisableIdleTimer(bool DisableIdle)
2127 {
2128  if ((m_priv->m_disableIdle = DisableIdle))
2129  m_idleTimer.stop();
2130  else
2131  m_idleTimer.start();
2132 }
2133 
2138 {
2139  if (m_priv->m_disableIdle)
2140  return;
2141 
2142  if (m_idleTime == 0min || !m_idleTimer.isActive() || (m_priv->m_standby && m_priv->m_enteringStandby))
2143  return;
2144 
2145  if (m_priv->m_standby)
2146  ExitStandby(false);
2147 
2148  m_idleTimer.start();
2149 }
2150 
2155 {
2156  if (m_priv->m_disableIdle)
2157  return;
2158 
2159  // don't do anything if the idle timer is disabled
2160  if (m_idleTime == 0min)
2161  return;
2162 
2163  if (Pause)
2164  {
2165  LOG(VB_GENERAL, LOG_NOTICE, "Suspending idle timer");
2166  m_idleTimer.stop();
2167  }
2168  else
2169  {
2170  LOG(VB_GENERAL, LOG_NOTICE, "Resuming idle timer");
2171  m_idleTimer.start();
2172  }
2173 
2174  // ResetIdleTimer();
2175 }
2176 
2178 {
2179  if (m_priv->m_disableIdle)
2180  return;
2181 
2182  m_priv->m_enteringStandby = false;
2183 
2184  if (m_idleTime > 0min && !m_priv->m_standby)
2185  {
2186  LOG(VB_GENERAL, LOG_NOTICE,
2187  QString("Entering standby mode after %1 minutes of inactivity").arg(m_idleTime.count()));
2188  EnterStandby(false);
2189  if (gCoreContext->GetNumSetting("idleTimeoutSecs", 0) > 0)
2190  {
2191  m_priv->m_enteringStandby = true;
2192  JumpTo("Standby Mode");
2193  }
2194  }
2195 }
2196 
2198 {
2199  if (Manual && m_priv->m_enteringStandby)
2200  m_priv->m_enteringStandby = false;
2201 
2202  if (m_priv->m_standby)
2203  return;
2204 
2205  // We've manually entered standby mode and we want to pause the timer
2206  // to prevent it being Reset
2207  if (Manual)
2208  {
2209  PauseIdleTimer(true);
2210  LOG(VB_GENERAL, LOG_NOTICE, QString("Entering standby mode"));
2211  }
2212 
2213  m_priv->m_standby = true;
2215 
2216  QVariantMap state;
2217  state.insert("state", "standby");
2218  state.insert("menutheme", GetMythDB()->GetSetting("menutheme", "defaultmenu"));
2219  state.insert("currentlocation", GetMythUI()->GetCurrentLocation());
2221 
2222  // Cache WOL settings in case DB goes down
2223  QString masterserver = gCoreContext->GetSetting("MasterServerName");
2224  gCoreContext->GetSettingOnHost("BackendServerAddr", masterserver);
2226  gCoreContext->GetSetting("WOLbackendCommand", "");
2227 
2228  // While in standby do not attempt to wake the backend
2229  gCoreContext->SetWOLAllowed(false);
2230 }
2231 
2233 {
2235  return;
2236 
2237  if (Manual)
2238  PauseIdleTimer(false);
2239  else if (gCoreContext->GetNumSetting("idleTimeoutSecs", 0) > 0)
2240  JumpTo("Main Menu");
2241 
2242  if (!m_priv->m_standby)
2243  return;
2244 
2245  LOG(VB_GENERAL, LOG_NOTICE, "Leaving standby mode");
2246  m_priv->m_standby = false;
2247 
2248  // We may attempt to wake the backend
2249  gCoreContext->SetWOLAllowed(true);
2251 
2252  QVariantMap state;
2253  state.insert("state", "idle");
2254  state.insert("menutheme", GetMythDB()->GetSetting("menutheme", "defaultmenu"));
2255  state.insert("currentlocation", GetMythUI()->GetCurrentLocation());
2257 }
2258 
2260 {
2261  LOG(VB_GENERAL, LOG_NOTICE, QString("Application State Changed to %1").arg(State));
2262  switch (State)
2263  {
2264  case Qt::ApplicationState::ApplicationActive:
2265  PopDrawDisabled();
2266  break;
2267  case Qt::ApplicationState::ApplicationSuspended:
2268  PushDrawDisabled();
2269  break;
2270  default:
2271  break;
2272  }
2273 }
2274 /* vim: set expandtab tabstop=4 shiftwidth=4: */
MythUIScreenBounds::m_alwaysOnTop
bool m_alwaysOnTop
Definition: mythuiscreenbounds.h:50
MythMainWindow::BindJump
void BindJump(const QString &Destination, const QString &Key)
Definition: mythmainwindow.cpp:1372
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MythCoreContext::SetWOLAllowed
void SetWOLAllowed(bool allow)
Definition: mythcorecontext.cpp:629
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:813
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
build_compdb.args
args
Definition: build_compdb.py:11
MythPainterWindow::DestroyPainters
static void DestroyPainters(MythPainterWindow *&PaintWin, MythPainter *&Painter)
Definition: mythpainterwindow.cpp:132
MythUIStateTracker::SetState
static void SetState(const QVariantMap &NewState)
Definition: mythuistatetracker.cpp:26
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:318
mythrect.h
mythevent.h
MythMainWindow::m_idleTimer
QTimer m_idleTimer
Definition: mythmainwindow.h:164
ExternalKeycodeEvent::kEventType
static const Type kEventType
Definition: mythevent.h:113
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:84
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:102
ACTION_DOWN
static constexpr const char * ACTION_DOWN
Definition: mythuiactions.h:17
MythMainWindow::closeEvent
void closeEvent(QCloseEvent *Event) override
Definition: mythmainwindow.cpp:477
MythEvent::kMythUserMessage
static const Type kMythUserMessage
Definition: mythevent.h:80
MythInputDeviceHandler::MainWindowReady
void MainWindowReady(void)
Definition: mythinputdevicehandler.cpp:198
MythEvent::kMythEventMessage
static const Type kMythEventMessage
Definition: mythevent.h:79
MythMainWindow::Init
void Init(bool MayReInit=true)
Definition: mythmainwindow.cpp:642
MythNotificationCenter::ProcessQueue
void ProcessQueue(void)
ProcessQueue will be called by the GUI event handler and will process all queued MythNotifications an...
Definition: mythnotificationcenter.cpp:1354
MythMainWindow::OnApplicationStateChange
void OnApplicationStateChange(Qt::ApplicationState State)
Definition: mythmainwindow.cpp:2259
MythDisplay::SwitchToDesktop
void SwitchToDesktop()
Return the screen to the original desktop video mode.
Definition: mythdisplay.cpp:681
MythMainWindowPrivate::m_mediaDeviceForCallback
MythMediaDevice * m_mediaDeviceForCallback
Definition: mythmainwindowprivate.h:69
GESTURE_TIMEOUT
static constexpr std::chrono::milliseconds GESTURE_TIMEOUT
Definition: mythmainwindow.cpp:64
MythMainWindow::SignalDisableScreensaver
void SignalDisableScreensaver()
MythMainWindowPrivate::m_pendingUpdate
bool m_pendingUpdate
Definition: mythmainwindowprivate.h:84
mythdb.h
MythPainter::SupportsClipping
virtual bool SupportsClipping(void)=0
MythMainWindowPrivate::m_longPressKeyCode
int m_longPressKeyCode
Definition: mythmainwindowprivate.h:88
MythMainWindow::SaveScreenShot
static bool SaveScreenShot(const QImage &Image, QString Filename="")
Definition: mythmainwindow.cpp:537
MythCoreContext::AllowShutdown
void AllowShutdown(void)
Definition: mythcorecontext.cpp:610
ACTION_SCREENSHOT
static constexpr const char * ACTION_SCREENSHOT
Definition: mythuiactions.h:22
MythEvent::kPushDisableDrawingEventType
static const Type kPushDisableDrawingEventType
Definition: mythevent.h:84
MythGesture::Recording
bool Recording()
Determine if the stroke is being recorded.
Definition: mythgesture.cpp:142
MythUIScreenBounds::UpdateScreenSettings
void UpdateScreenSettings(MythDisplay *mDisplay)
Definition: mythuiscreenbounds.cpp:144
MythMainWindow::SignalWindowReady
void SignalWindowReady()
LONGPRESS_INTERVAL
static constexpr std::chrono::milliseconds LONGPRESS_INTERVAL
Definition: mythmainwindow.cpp:66
MythEvent::kEnableUDPListenerEventType
static const Type kEnableUDPListenerEventType
Definition: mythevent.h:90
MythGesture::Start
void Start()
Start recording.
Definition: mythgesture.cpp:151
MythMainWindowPrivate::m_gestureTimer
QTimer * m_gestureTimer
Definition: mythmainwindowprivate.h:75
MythEvent::kUnlockInputDevicesEventType
static const Type kUnlockInputDevicesEventType
Definition: mythevent.h:87
MythUIScreenBounds::m_wantFullScreen
bool m_wantFullScreen
Definition: mythuiscreenbounds.h:48
MythMainWindow::MythMainWindow
MythMainWindow(bool UseDB=true)
Definition: mythmainwindow.cpp:131
MythMainWindowPrivate::m_useDB
bool m_useDB
To allow or prevent database access.
Definition: mythmainwindowprivate.h:59
MythInputDeviceHandler::Action
void Action(const QString &Action)
Definition: mythinputdevicehandler.cpp:179
MythMainWindow::GetStackCount
int GetStackCount()
Definition: mythmainwindow.cpp:313
MythMainWindow::JumpTo
void JumpTo(const QString &Destination, bool Pop=true)
Definition: mythmainwindow.cpp:1458
MythMainWindowPrivate::m_disableIdle
bool m_disableIdle
Definition: mythmainwindowprivate.h:82
MythMainWindow::getMainWindow
static MythMainWindow * getMainWindow(bool UseDB=true)
Return the existing main window, or create one.
Definition: mythmainwindow.cpp:80
MythUIScreenBounds::m_qtFullScreen
bool m_qtFullScreen
Definition: mythuiscreenbounds.h:49
MythMainWindow::ClearAllJumps
void ClearAllJumps()
Definition: mythmainwindow.cpp:1450
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MythMainWindowPrivate::m_stackList
QVector< MythScreenStack * > m_stackList
Definition: mythmainwindowprivate.h:72
ACTION_0
static constexpr const char * ACTION_0
Definition: mythuiactions.h:4
MythDate::kScreenShotFilename
@ kScreenShotFilename
"yyyy-MM-ddThh-mm-ss.zzz"
Definition: mythdate.h:29
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MythScreenStack
Definition: mythscreenstack.h:16
MythMainWindow::RestoreScreensaver
static void RestoreScreensaver()
Definition: mythmainwindow.cpp:577
MythEvent::kDisableUDPListenerEventType
static const Type kDisableUDPListenerEventType
Definition: mythevent.h:89
MythMainWindow::ShowMouseCursor
void ShowMouseCursor(bool Show)
Definition: mythmainwindow.cpp:2107
ACTION_LEFT
static constexpr const char * ACTION_LEFT
Definition: mythuiactions.h:18
MythMainWindow::ReloadKeys
void ReloadKeys()
Definition: mythmainwindow.cpp:954
MythMainWindowPrivate::m_popwindows
bool m_popwindows
Definition: mythmainwindowprivate.h:57
MythNotification
Definition: mythnotification.h:29
MythMainWindow::LoadQtConfig
static void LoadQtConfig()
Definition: mythmainwindow.cpp:634
MythMainWindowPrivate::m_exitingtomain
bool m_exitingtomain
Definition: mythmainwindowprivate.h:56
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:619
MythMainWindowPrivate::m_longPressTime
std::chrono::milliseconds m_longPressTime
Definition: mythmainwindowprivate.h:89
MythMainWindowPrivate::m_exitMenuMediaDeviceCallback
void(* m_exitMenuMediaDeviceCallback)(MythMediaDevice *mediadevice)
Definition: mythmainwindowprivate.h:68
MythCoreContext::IsUIThread
bool IsUIThread(void)
Definition: mythcorecontext.cpp:1348
MythScreenSaverControl::Reset
void Reset()
MythMainWindow::HandleTVAction
void HandleTVAction(const QString &Action)
Definition: mythmainwindow.cpp:1522
MythMediaEvent::kEventType
static const Type kEventType
Definition: mythmedia.h:193
MythMainWindow::Show
void Show()
Definition: mythmainwindow.cpp:962
MythMainWindowPrivate::m_mediaPluginMap
QMap< QString, MythMediaCallback > m_mediaPluginMap
Definition: mythmainwindowprivate.h:64
MythMainWindow::customEvent
void customEvent(QEvent *Event) override
Definition: mythmainwindow.cpp:1895
MythMainWindow::ResetIdleTimer
void ResetIdleTimer()
Reset the idle timeout timer.
Definition: mythmainwindow.cpp:2137
STANDBY_TIMEOUT
static constexpr std::chrono::minutes STANDBY_TIMEOUT
Definition: mythmainwindow.cpp:65
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
mythinputdevicehandler.h
MythMainWindow::ClearJump
void ClearJump(const QString &Destination)
Definition: mythmainwindow.cpp:1352
MythPainterWindow::CreatePainters
static QString CreatePainters(MythMainWindow *MainWin, MythPainterWindow *&PaintWin, MythPainter *&Paint)
Definition: mythpainterwindow.cpp:53
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
show
static void show(uint8_t *buf, int length)
Definition: ringbuffer.cpp:339
MythMainWindowPrivate::m_actionText
QHash< QString, QHash< QString, QString > > m_actionText
Definition: mythmainwindowprivate.h:65
MythMainWindow::DoRemoteScreenShot
void DoRemoteScreenShot(const QString &Filename, int Width, int Height)
Definition: mythmainwindow.cpp:519
MythMainWindow::RegisterKey
void RegisterKey(const QString &Context, const QString &Action, const QString &Description, const QString &Key)
Definition: mythmainwindow.cpp:1250
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
MythMainWindow::RegisterMediaPlugin
void RegisterMediaPlugin(const QString &Name, const QString &Desc, MediaPlayCallback Func)
Definition: mythmainwindow.cpp:1481
MythMainWindow::Draw
void Draw(MythPainter *Painter=nullptr)
Definition: mythmainwindow.cpp:436
mythdirs.h
MythScreenSaverControl::Restore
void Restore()
MythMainWindow::GetRenderDevice
MythRender * GetRenderDevice()
Definition: mythmainwindow.cpp:292
MythMainWindowPrivate::m_hideMouseTimer
QTimer * m_hideMouseTimer
Definition: mythmainwindowprivate.h:76
MythMainWindow::GetPainter
MythPainter * GetPainter()
Definition: mythmainwindow.cpp:258
ACTION_SELECT
static constexpr const char * ACTION_SELECT
Definition: mythuiactions.h:15
MythGestureEvent::kEventType
static const Type kEventType
Definition: mythgesture.h:91
ACTION_9
static constexpr const char * ACTION_9
Definition: mythuiactions.h:13
MythMainWindow::PopScreenStack
void PopScreenStack()
Definition: mythmainwindow.cpp:304
mythmainwindowprivate.h
HasMythMainWindow
bool HasMythMainWindow(void)
Definition: mythmainwindow.cpp:109
MythMainWindow::SignalSetDrawEnabled
void SignalSetDrawEnabled(bool Enable)
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
MythCoreContext::ResetAudioLanguage
void ResetAudioLanguage(void)
Definition: mythcorecontext.cpp:1821
MythEvent::Message
const QString & Message() const
Definition: mythevent.h:65
MythMainWindow::HandleMedia
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
Definition: mythmainwindow.cpp:1497
MythMainWindowPrivate::TranslateKeyNum
static int TranslateKeyNum(QKeyEvent *Event)
Definition: mythmainwindowprivate.cpp:8
MythMainWindow::ClearKey
void ClearKey(const QString &Context, const QString &Action)
Definition: mythmainwindow.cpp:1188
Action
An action (for this plugin) consists of a description, and a set of key sequences.
Definition: action.h:40
MythMainWindow::AddScreenStack
void AddScreenStack(MythScreenStack *Stack, bool Main=false)
Definition: mythmainwindow.cpp:297
MythMainWindow::SetEffectsEnabled
void SetEffectsEnabled(bool Enable)
Definition: mythmainwindow.cpp:1029
mythpainterwindow.h
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
MythMainWindow::DisableIdleTimer
void DisableIdleTimer(bool DisableIdle=true)
Disable the idle timeout timer.
Definition: mythmainwindow.cpp:2126
MythMainWindow::GetDisplay
MythDisplay * GetDisplay()
Definition: mythmainwindow.cpp:253
MythMainWindow::DisableScreensaver
static void DisableScreensaver()
Definition: mythmainwindow.cpp:583
MythMainWindow::SignalRestoreScreensaver
void SignalRestoreScreensaver()
MythMainWindow::GetKey
static QString GetKey(const QString &Context, const QString &Action)
Definition: mythmainwindow.cpp:1319
MythThemeBase
Definition: myththemebase.h:11
ExternalKeycodeEvent
Definition: mythevent.h:105
MythMainWindow::KeyLongPressFilter
bool KeyLongPressFilter(QEvent **Event, QScopedPointer< QEvent > &NewEvent)
Definition: mythmainwindow.cpp:1547
MythGesture::Stop
void Stop(bool Timeout=false)
Stop recording.
Definition: mythgesture.cpp:163
mythdate.h
MythMainWindow::SetDrawEnabled
void SetDrawEnabled(bool Enable)
Definition: mythmainwindow.cpp:1005
mythrender_base.h
MythScreenSaverControl::Asleep
bool Asleep()
Definition: mythscreensaver.cpp:77
MythMainWindow::m_screensaver
MythScreenSaverControl * m_screensaver
Definition: mythmainwindow.h:163
MythMainWindowPrivate::m_exitMenuCallback
void(* m_exitMenuCallback)(void)
Definition: mythmainwindowprivate.h:67
mythdisplay.h
mythlogging.h
MythMainWindow::HideMouseTimeout
void HideMouseTimeout()
Definition: mythmainwindow.cpp:2118
ACTION_1
static constexpr const char * ACTION_1
Definition: mythuiactions.h:5
MythMainWindowPrivate
Definition: mythmainwindowprivate.h:47
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1112
s_mainWin
static MythMainWindow * s_mainWin
Definition: mythmainwindow.cpp:70
MythMainWindow::event
bool event(QEvent *Event) override
Definition: mythmainwindow.cpp:613
ACTION_TVPOWERON
static constexpr const char * ACTION_TVPOWERON
Definition: mythuiactions.h:25
MythMainWindow::destroyMainWindow
static void destroyMainWindow()
Definition: mythmainwindow.cpp:96
MythInputDeviceHandler
A wrapper around sundry external input devices.
Definition: mythinputdevicehandler.h:18
MythMainWindowPrivate::m_destinationMap
QMap< QString, JumpData > m_destinationMap
Definition: mythmainwindowprivate.h:63
MythMainWindow::m_themeBase
MythThemeBase * m_themeBase
Definition: mythmainwindow.h:159
Event
Event details.
Definition: zmdefines.h:26
MythMainWindowPrivate::m_drawDisabledDepth
uint m_drawDisabledDepth
Definition: mythmainwindowprivate.h:78
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:551
compat.h
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
MythMainWindow::HidePainterWindow
void HidePainterWindow()
Definition: mythmainwindow.cpp:282
MythMainWindow::ExitToMainMenu
void ExitToMainMenu()
Definition: mythmainwindow.cpp:1045
MythCoreContext::GetDurSetting
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
Definition: mythcorecontext.h:168
mythscreensaver.h
MythMediaEvent
Definition: mythmedia.h:183
MythMainWindowPrivate::m_keyContexts
QHash< QString, KeyContext * > m_keyContexts
Definition: mythmainwindowprivate.h:61
MythMainWindow::ShowPainterWindow
void ShowPainterWindow()
Definition: mythmainwindow.cpp:273
State
State
Definition: zmserver.h:68
MythMainWindow::DestinationExists
bool DestinationExists(const QString &Destination) const
Definition: mythmainwindow.cpp:1471
DestroyMythMainWindow
void DestroyMythMainWindow(void)
Definition: mythmainwindow.cpp:114
MythNotificationCenter::DisplayedNotifications
int DisplayedNotifications(void) const
Returns number of notifications currently displayed.
Definition: mythnotificationcenter.cpp:1411
MythDisplay::SetWidget
void SetWidget(QWidget *MainWindow)
Set the QWidget and QWindow in use.
Definition: mythdisplay.cpp:246
MythCoreContext::GetDB
MythDB * GetDB(void)
Definition: mythcorecontext.cpp:1753
mythmedia.h
MythUIScreenBounds::m_screenRect
QRect m_screenRect
Definition: mythuiscreenbounds.h:44
MythUIScreenBounds::SetUIScreenRect
void SetUIScreenRect(QRect Rect)
Definition: mythuiscreenbounds.cpp:203
MythMainWindowPrivate::m_drawDisableLock
QMutex m_drawDisableLock
Definition: mythmainwindowprivate.h:77
MythMainWindow::RemoteScreenShot
void RemoteScreenShot(QString Filename, int Width, int Height)
Definition: mythmainwindow.cpp:530
MythScreenSaverControl
Controls all instances of the screensaver.
Definition: mythscreensaver.h:33
MythGesture::Record
bool Record(QPoint Point, Qt::MouseButton Button)
Record a point.
Definition: mythgesture.cpp:331
MythMainWindow::eventFilter
bool eventFilter(QObject *Watched, QEvent *Event) override
Definition: mythmainwindow.cpp:1645
MythMainWindow::Animate
void Animate()
Definition: mythmainwindow.cpp:338
JumpData::m_destination
QString m_destination
Definition: mythmainwindowprivate.h:39
MythGestureEvent::Click
@ Click
Definition: mythgesture.h:77
MythGestureEvent::SetPosition
void SetPosition(QPoint Position)
Definition: mythgesture.h:86
MythMainWindowPrivate::m_escapekey
int m_escapekey
Definition: mythmainwindowprivate.h:71
MythInputDeviceHandler::Reset
void Reset(void)
Definition: mythinputdevicehandler.cpp:156
MythNotificationCenterEvent::kEventType
static const Type kEventType
Definition: mythnotificationcenter.h:30
ACTION_8
static constexpr const char * ACTION_8
Definition: mythuiactions.h:12
MythMainWindow::GetPaintWindow
QWidget * GetPaintWindow()
Definition: mythmainwindow.cpp:268
mythpainter.h
MythMainWindow::RegisterJump
void RegisterJump(const QString &Destination, const QString &Description, const QString &Key, void(*Callback)(void), bool Exittomain=true, QString LocalAction="")
Definition: mythmainwindow.cpp:1413
MythMainWindow::IsTopScreenInitialized
static bool IsTopScreenInitialized()
Definition: mythmainwindow.cpp:606
MythEvent::kMythPostShowEventType
static const Type kMythPostShowEventType
Definition: mythevent.h:83
JumpData
Definition: mythmainwindowprivate.h:36
ACTION_TVPOWEROFF
static constexpr const char * ACTION_TVPOWEROFF
Definition: mythuiactions.h:24
MythMainWindow::SignalRemoteScreenShot
void SignalRemoteScreenShot(QString Filename, int Width, int Height)
MSqlQuery::isConnected
bool isConnected(void) const
Only updated once during object creation.
Definition: mythdbcon.h:137
uint
unsigned int uint
Definition: compat.h:81
ACTION_7
static constexpr const char * ACTION_7
Definition: mythuiactions.h:11
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
MythPainterWindow::GetRenderDevice
MythRender * GetRenderDevice()
Definition: mythpainterwindow.cpp:157
mythuistatetracker.h
MythMainWindow::GetStackAt
MythScreenStack * GetStackAt(int Position)
Definition: mythmainwindow.cpp:331
MythDisplay
Definition: mythdisplay.h:22
MythMainWindow::EnumerateDestinations
QStringList EnumerateDestinations() const
Definition: mythmainwindow.cpp:1476
MythMainWindow::m_refreshTimer
QTimer m_refreshTimer
Definition: mythmainwindow.h:158
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:912
mythgesture.h
A C++ ripoff of the stroke library for MythTV.
MythMainWindowPrivate::m_enteringStandby
bool m_enteringStandby
Definition: mythmainwindowprivate.h:81
ACTION_HANDLEMEDIA
static constexpr const char * ACTION_HANDLEMEDIA
Definition: mythuiactions.h:21
MythPainter::End
virtual void End()
Definition: mythpainter.h:55
MythMainWindow::PushDrawDisabled
uint PushDrawDisabled()
Definition: mythmainwindow.cpp:984
MythEvent::kPopDisableDrawingEventType
static const Type kPopDisableDrawingEventType
Definition: mythevent.h:85
MythMainWindow::m_priv
MythMainWindowPrivate * m_priv
Definition: mythmainwindow.h:155
ACTION_UP
static constexpr const char * ACTION_UP
Definition: mythuiactions.h:16
MythMainWindow::GetCurrentNotificationCenter
MythNotificationCenter * GetCurrentNotificationCenter()
Definition: mythmainwindow.cpp:263
MythMainWindow::m_idleTime
std::chrono::minutes m_idleTime
Definition: mythmainwindow.h:165
MythPainter::GetName
virtual QString GetName(void)=0
MythUDP::EnableUDPListener
static void EnableUDPListener(bool Enable=true)
Definition: mythudplistener.cpp:173
mythuihelper.h
MythCoreContext::GetMasterServerPort
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
Definition: mythcorecontext.cpp:980
MythUIScreenBounds::InitScreenBounds
void InitScreenBounds()
Definition: mythuiscreenbounds.cpp:130
MythMainWindow::~MythMainWindow
~MythMainWindow() override
Definition: mythmainwindow.cpp:210
ACTION_4
static constexpr const char * ACTION_4
Definition: mythuiactions.h:8
MythMainWindow::paintEngine
QPaintEngine * paintEngine() const override
Definition: mythmainwindow.cpp:472
MythUIScreenBounds::m_wantWindow
bool m_wantWindow
Definition: mythuiscreenbounds.h:47
mythmiscutil.h
ACTION_3
static constexpr const char * ACTION_3
Definition: mythuiactions.h:7
MythScreenSaverControl::Disable
void Disable()
MythUIScreenBounds::WindowIsAlwaysFullscreen
static bool WindowIsAlwaysFullscreen()
Return true if the current platform only supports fullscreen windows.
Definition: mythuiscreenbounds.cpp:115
ACTION_GETSTATUS
static constexpr const char * ACTION_GETSTATUS
Definition: mythuiactions.h:27
MythMainWindow::GetTarget
QObject * GetTarget(QKeyEvent &Key)
Definition: mythmainwindow.cpp:2082
ACTION_RIGHT
static constexpr const char * ACTION_RIGHT
Definition: mythuiactions.h:19
mythcorecontext.h
MythMainWindow::EnterStandby
void EnterStandby(bool Manual=true)
Definition: mythmainwindow.cpp:2197
MythRender
Definition: mythrender_base.h:23
MythScreenType::inputMethodEvent
bool inputMethodEvent(QInputMethodEvent *event) override
Input Method event handler.
Definition: mythscreentype.cpp:398
MediaPlayCallback
int(*)(const QString &, const QString &, const QString &, const QString &, const QString &, int, int, const QString &, std::chrono::minutes, const QString &, const QString &, bool) MediaPlayCallback
Definition: mythmainwindow.h:19
MythPainter
Definition: mythpainter.h:34
MythDisplay::SwitchToGUI
bool SwitchToGUI(bool Wait=false)
Switches to the GUI resolution.
Definition: mythdisplay.cpp:774
MythMainWindow::InitKeys
void InitKeys()
Definition: mythmainwindow.cpp:793
MythMainWindow::m_display
MythDisplay * m_display
Definition: mythmainwindow.h:156
MythCoreContext::ResetLanguage
void ResetLanguage(void)
Definition: mythcorecontext.cpp:1787
myththemebase.h
MythMainWindow::PopDrawDisabled
uint PopDrawDisabled()
Definition: mythmainwindow.cpp:993
mythudplistener.h
Name
Definition: channelsettings.cpp:71
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:926
MythMainWindow::IsScreensaverAsleep
static bool IsScreensaverAsleep()
Definition: mythmainwindow.cpp:595
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:889
MythMainWindow::m_repaintRegion
QRegion m_repaintRegion
Definition: mythmainwindow.h:157
MythMainWindowPrivate::m_allowInput
bool m_allowInput
Definition: mythmainwindowprivate.h:83
ACTION_5
static constexpr const char * ACTION_5
Definition: mythuiactions.h:9
MythMainWindow::m_deviceHandler
MythInputDeviceHandler * m_deviceHandler
Definition: mythmainwindow.h:162
GetNotificationCenter
MythNotificationCenter * GetNotificationCenter(void)
Definition: mythmainwindow.cpp:124
MythUIThemeCache::UpdateImageCache
void UpdateImageCache()
Definition: mythuithemecache.cpp:61
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythUIType::ContainsPoint
bool ContainsPoint(QPoint point) const
Check if the given point falls within this widgets area.
Definition: mythuitype.cpp:1416
build_compdb.action
action
Definition: build_compdb.py:9
MythMainWindow::MouseTimeout
void MouseTimeout()
Definition: mythmainwindow.cpp:1532
MythMainWindowPrivate::m_jumpMap
QMap< int, JumpData * > m_jumpMap
Definition: mythmainwindowprivate.h:62
MythMainWindowPrivate::m_gesture
MythGesture m_gesture
Definition: mythmainwindowprivate.h:74
MythMainWindow::DelayedAction
void DelayedAction()
Definition: mythmainwindow.cpp:779
MythMainWindow::IsExitingToMain
bool IsExitingToMain() const
Definition: mythmainwindow.cpp:1040
MythMainWindowPrivate::m_firstinit
bool m_firstinit
Definition: mythmainwindowprivate.h:86
MythScreenType::gestureEvent
bool gestureEvent(MythGestureEvent *event) override
Mouse click/movement handler, receives mouse gesture events from the QCoreApplication event loop.
Definition: mythscreentype.cpp:446
MythPainter::SetClipRect
virtual void SetClipRect(QRect clipRect)
Definition: mythpainter.cpp:46
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:323
MythEvent::kExitToMainMenuEventType
static const Type kExitToMainMenuEventType
Definition: mythevent.h:82
MythThemeBase::Reload
void Reload()
Definition: myththemebase.cpp:37
MythGesture::GetGesture
MythGestureEvent * GetGesture() const
Complete the gesture event of the last completed stroke.
Definition: mythgesture.cpp:190
KeyContext
Definition: mythmainwindowprivate.h:12
MythMainWindow::ClearKeyContext
void ClearKeyContext(const QString &Context)
Definition: mythmainwindow.cpp:1205
MythMainWindow::SignalResetScreensaver
void SignalResetScreensaver()
mythuiactions.h
MythMediaDevice
Definition: mythmedia.h:48
MythNotificationCenter::GetInstance
static MythNotificationCenter * GetInstance(void)
returns the MythNotificationCenter singleton
Definition: mythnotificationcenter.cpp:1318
MythPainterWindow::RenderIsShared
bool RenderIsShared()
Definition: mythpainterwindow.cpp:162
MythGestureEvent
A custom event that represents a mouse gesture.
Definition: mythgesture.h:39
MythMainWindow::m_painterWin
MythPainterWindow * m_painterWin
Definition: mythmainwindow.h:161
MythMainWindow::MoveResize
void MoveResize(QRect &Geometry)
Definition: mythmainwindow.cpp:973
MythDisplay::UsingVideoModes
virtual bool UsingVideoModes()
Definition: mythdisplay.h:30
MythCoreContext::BlockShutdown
void BlockShutdown(void)
Definition: mythcorecontext.cpp:596
ACTION_2
static constexpr const char * ACTION_2
Definition: mythuiactions.h:6
MythNotificationCenter
Definition: mythnotificationcenter.h:40
GetMythPainter
MythPainter * GetMythPainter(void)
Definition: mythmainwindow.cpp:119
s_mainLock
static QMutex s_mainLock
Definition: mythmainwindow.cpp:71
MythMainWindow::GrabWindow
static void GrabWindow(QImage &Image)
Definition: mythmainwindow.cpp:490
MythMainWindow::ResetScreensaver
static void ResetScreensaver()
Definition: mythmainwindow.cpp:589
MythMainWindow::AllowInput
void AllowInput(bool Allow)
Definition: mythmainwindow.cpp:1527
MythUIThemeCache::ClearThemeCacheDir
void ClearThemeCacheDir()
Definition: mythuithemecache.cpp:56
mythburn.usebookmark
bool usebookmark
Definition: mythburn.py:179
MythMainWindow::IdleTimeout
void IdleTimeout()
Definition: mythmainwindow.cpp:2177
MythInputDeviceHandler::Event
void Event(QEvent *Event) const
Definition: mythinputdevicehandler.cpp:163
GetMythUI
MythUIHelper * GetMythUI()
Definition: mythuihelper.cpp:66
MythMainWindow::ScreenShot
static bool ScreenShot(int Width=0, int Height=0, QString Filename="")
Definition: mythmainwindow.cpp:565
build_compdb.filename
filename
Definition: build_compdb.py:21
MythMainWindow::RestartInputHandlers
void RestartInputHandlers()
Definition: mythmainwindow.cpp:2102
MythMainWindowPrivate::m_mainStack
MythScreenStack * m_mainStack
Definition: mythmainwindowprivate.h:73
mythmainwindow.h
MythMainWindowPrivate::m_standby
bool m_standby
Definition: mythmainwindowprivate.h:80
MythMainWindow::m_painter
MythPainter * m_painter
Definition: mythmainwindow.h:160
MythScreenType::IsInitialized
bool IsInitialized(void) const
Has Init() been called on this screen?
Definition: mythscreentype.cpp:360
MythCoreContext::dispatch
void dispatch(const MythEvent &event)
Definition: mythcorecontext.cpp:1719
MythMainWindow::GetActionText
QString GetActionText(const QString &Context, const QString &Action) const
Definition: mythmainwindow.cpp:1340
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:562
MythPainter::Begin
virtual void Begin(QPaintDevice *)
Definition: mythpainter.h:54
MythMainWindow::BindKey
void BindKey(const QString &Context, const QString &Action, const QString &Key)
Definition: mythmainwindow.cpp:1212
MythMainWindow::ExitStandby
void ExitStandby(bool Manual=true)
Definition: mythmainwindow.cpp:2232
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55
MythDisplay::Create
static MythDisplay * Create(MythMainWindow *MainWindow)
Create a MythDisplay object appropriate for the current platform.
Definition: mythdisplay.cpp:83
ACTION_6
static constexpr const char * ACTION_6
Definition: mythuiactions.h:10
MythMainWindowPrivate::m_nc
MythNotificationCenter * m_nc
Definition: mythmainwindowprivate.h:79
MythMainWindow
Definition: mythmainwindow.h:28
MythMainWindow::drawScreen
void drawScreen(QPaintEvent *Event=nullptr)
Definition: mythmainwindow.cpp:376
MythCoreContext::SetGUIObject
void SetGUIObject(QObject *gui)
Definition: mythcorecontext.cpp:1733
mythscreentype.h
MythUIScreenBounds::GeometryIsOverridden
static bool GeometryIsOverridden()
Definition: mythuiscreenbounds.cpp:20
MythUIScreenBounds::m_uiScreenRect
QRect m_uiScreenRect
Definition: mythuiscreenbounds.h:43
MythMainWindow::PauseIdleTimer
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
Definition: mythmainwindow.cpp:2154
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:898
MythUDP::StopUDPListener
static void StopUDPListener()
Definition: mythudplistener.cpp:213
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:838
MythInputDeviceHandler::IgnoreKeys
void IgnoreKeys(bool Ignore)
Definition: mythinputdevicehandler.cpp:186
MythScreenStack::GetTopScreen
virtual MythScreenType * GetTopScreen(void) const
Definition: mythscreenstack.cpp:182
MythNotificationCenter::Queue
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
Definition: mythnotificationcenter.cpp:1349
MythEvent::kLockInputDevicesEventType
static const Type kLockInputDevicesEventType
Definition: mythevent.h:86