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