-
-
Save xim/ee56564f425151ea2fa70f730d644873 to your computer and use it in GitHub Desktop.
autohide-test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*.user | |
Makefile* | |
.qmake.stash | |
release | |
debug | |
*.swp | |
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
QT += widgets | |
TARGET = autohide-test | |
TEMPLATE = app | |
SOURCES += \ | |
main.cpp \ | |
mainwindow.cpp \ | |
HEADERS += \ | |
mainwindow.h \ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "mainwindow.h" | |
#include <QApplication> | |
int main(int argc, char *argv[]) | |
{ | |
QApplication a(argc, argv); | |
MainWindow w; | |
w.show(); | |
return a.exec(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "mainwindow.h" | |
#include <QApplication> | |
#include <QKeyEvent> | |
#include <QLabel> | |
MainWindow::MainWindow(QWidget *parent) | |
: QMainWindow(parent) | |
{ | |
ahMenuBar = new AutoHidingMenuBar; | |
setMenuBar(ahMenuBar); | |
#if defined(USE_HIDE) | |
#elif defined(USE_SETMAXHEIGHT) || defined(USE_NOTHING) | |
ahMenuBar->show(); | |
#else | |
#error "missing implementation?" | |
#endif | |
ahMenuBar->setVisibleCustom(false); | |
auto fileMenu = menuBar()->addMenu("&File"); | |
fileMenu->addAction("&Quit", qApp, &QCoreApplication::quit, QKeySequence::Quit); | |
fileMenu->addAction("Q&uit2", qApp, &QCoreApplication::quit, QKeySequence::Close); | |
auto viewMenu = menuBar()->addMenu("&View"); | |
viewMenu->addAction("&Quit", qApp, &QCoreApplication::quit, QKeySequence::HelpContents); | |
viewMenu->addAction("Q&uit2", qApp, &QCoreApplication::quit, QKeySequence::FullScreen); | |
setCentralWidget(new QLabel("No can has contents")); | |
centralWidget()->setFocusPolicy(Qt::StrongFocus); | |
} | |
MainWindow::~MainWindow() | |
{ | |
} | |
#if defined(USE_HIDE) | |
void MainWindow::keyPressEvent(QKeyEvent *event) { | |
if ((!event->key() || event->key() == Qt::Key_Alt) && event->modifiers() == Qt::AltModifier) | |
lastWasAltPress = true; | |
else | |
lastWasAltPress = false; | |
QMainWindow::keyPressEvent(event); | |
} | |
void MainWindow::keyReleaseEvent(QKeyEvent *event) { | |
if (lastWasAltPress && event->key() == Qt::Key_Alt && event->modifiers() == Qt::NoModifier) { | |
if (ahMenuBar->isVisible()) { | |
qDebug("Hiding after alt key press and visible"); | |
ahMenuBar->hide(); | |
} else { | |
qDebug("Showing after alt key press"); | |
ahMenuBar->show(); | |
} | |
lastWasAltPress = false; | |
} | |
QMainWindow::keyReleaseEvent(event); | |
} | |
#endif | |
AutoHidingMenuBar::AutoHidingMenuBar() : QMenuBar() { | |
connect(qApp, &QApplication::focusChanged, this, &AutoHidingMenuBar::focusChanged); | |
} | |
bool AutoHidingMenuBar::isVisibleCustom() { | |
#if defined(USE_HIDE) | |
return isVisible(); | |
#elif defined(USE_SETMAXHEIGHT) | |
return maximumHeight() != 0; | |
#elif defined(USE_NOTHING) | |
return true; | |
#else | |
#error "missing implementation?" | |
#endif | |
} | |
void AutoHidingMenuBar::setVisibleCustom(bool visible) { | |
#if defined(USE_HIDE) | |
if (visible) | |
show(); | |
else | |
hide(); | |
#elif defined(USE_SETMAXHEIGHT) | |
if (visible) { | |
auto action = activeAction(); | |
setMaximumHeight(100); | |
if (action) { | |
// XXX This is a bit of a hack. We could do | |
// QCoreApplication::processEvents(); | |
// setActiveAction(action); | |
// with almost the same effect, but then we *open* the first menu on single alt press... | |
auto evt = new QMouseEvent(QEvent::MouseMove, actionGeometry(action).center(), Qt::NoButton, Qt::NoButton, Qt::NoModifier); | |
QCoreApplication::postEvent(this, evt); | |
} | |
} else | |
setMaximumHeight(0); | |
#elif defined(USE_NOTHING) | |
Q_UNUSED(visible) | |
#else | |
#error "missing implementation?" | |
#endif | |
} | |
void AutoHidingMenuBar::focusChanged(QWidget *, QWidget * focus) { | |
bool inFocus = hasFocus() || isAncestorOf(focus) || hasFocusedChild(); | |
if (inFocus && !isVisibleCustom()) { | |
qDebug("Came into focus, should appear."); | |
setVisibleCustom(true); | |
} else if (!inFocus && isVisibleCustom()) { | |
qDebug("Lost focus on menu bar, should hide."); | |
setVisibleCustom(false); | |
} | |
} | |
bool AutoHidingMenuBar::hasFocusedChild() { | |
QObjectList queue{children()}; | |
while (!queue.empty()) { | |
auto child = queue.takeFirst(); | |
auto widget = dynamic_cast<QWidget *>(child); | |
if (widget && widget->hasFocus()) | |
return true; | |
queue.append(child->children()); | |
} | |
return false; | |
} | |
#if defined(DEBUG_EVENTS) | |
bool AutoHidingMenuBar::eventFilter(QObject * obj, QEvent * event) { | |
if (event->type() == QEvent::HoverMove) { | |
auto hoverEvent = dynamic_cast<QHoverEvent *>(event); | |
qDebug("Hover at %dx%d", hoverEvent->pos().x(), hoverEvent->pos().y()); | |
} | |
return QMenuBar::eventFilter(obj, event); | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MAINWINDOW_H | |
#define MAINWINDOW_H | |
#include <QMainWindow> | |
#include <QMenuBar> | |
//#define USE_HIDE | |
#define USE_SETMAXHEIGHT | |
//#define USE_NOTHING | |
//#define DEBUG_EVENTS | |
class AutoHidingMenuBar : public QMenuBar { | |
Q_OBJECT | |
public: | |
AutoHidingMenuBar(); | |
bool isVisibleCustom(); | |
void setVisibleCustom(bool visible); | |
#if defined(DEBUG_EVENTS) | |
protected: | |
bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; | |
#endif | |
private slots: | |
void focusChanged(QWidget *from, QWidget *to); | |
private: | |
bool hasFocusedChild(); | |
}; | |
class MainWindow : public QMainWindow | |
{ | |
Q_OBJECT | |
public: | |
MainWindow(QWidget *parent = 0); | |
~MainWindow(); | |
#if defined(USE_HIDE) | |
protected: | |
void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE; | |
void keyReleaseEvent(QKeyEvent *) Q_DECL_OVERRIDE; | |
private: | |
bool lastWasAltPress = false; | |
#endif | |
private: | |
AutoHidingMenuBar * ahMenuBar; | |
}; | |
#endif // MAINWINDOW_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment