Qt4: Making fullscreen window impossible to get around (a lock screen)? - c++

My application is an OS lock screen (like GDM's lock screen or KDE's), so I'm trying to make it function like one.
I am trying to make my application's window hover above all other windows and disable/intercept all keyboard shortcuts (ALT-TAB, CTRL-ALT-D, etc.) that would cause it disappear.
Is there any way to do this? I'm 100% sure there is, as lock screens with GUIs exist, but I just can't find the place to look...

I don't know how to do it with Qt, but what you are looking for is called grabbing. You can grab the pointer input device as well as the keyboard.
Edit: Looking in to the Qt4 docs, have you tried to use QWidget::grabMouse? It looks like this function does exactly what you want.

I don't know if this is the best solution, but you can try an event handler using QObject::installEventFilter().
If you are using Windows, you can install an event filter that handles messages where event->type() == QEvent::WinEventAct.
I don't really know much about other OSs, but Qt probably has something for that too.

inherit Qwidget class with parameter Qt::WindowStaysOnTopHint see below
myclass::myclass(QWidget *parent) : QWidget(parent,Qt::WindowStaysOnTopHint)

Related

How to detect a Windows event in Qt?

I am trying to build an app to detect Windows events, in particular events related to multimedia (playing video, playing audio and images).
For instance, if Windows Media Player is opened, the related event should be detected.
There is no 'events' for that.
You can detect the lauches of media players (by winapi ::FindWindow) or image viewers.
I don't think it's possible to do this with QT's built in functions alone. You'll have to use the Windows API. Depending on what you actually want to do this can get quite complicated.
If you just want to check if a certain application has been started yet, you could use the FindWindow function. I'd suggest to use a qt timer to create signals that you can use to check if the Window has opened yet.
QTimer::singleShot(200, this, SLOT(checkForMediaPlayer()));
Just add this to your QObject along with the checkForMediaPlayer member function that'll do whatever you want once the MediaPlayer has been detected.

QT How to embed an application into QT widget

In our project we have three independent applications, and we have to develop a QT control application that controls these three applications. The main window will be seperated to three sub windows - each one display another one application.
I thought to use QX11EmbedWidget and QX11EmbedContainer widgets, but two problems with that:
The QX11Embed* is based on X11 protocol and I dont know if it's supported on non-x11 systems like Windows OS.
Since QT 5 these classes are not existing, and the QT documentation doesn't mention why.
So that I dont know whether to use it or not - I'll be happy to get an answers.
In addition, I see that the QT 5.1 contains QWidget::createWindowContainer(); function that in some posts it looks like this should be the replacement to the X11Embed. Can anyone please explian me more how can I use this function to create a QT widget that will run another application (a Calculator for example) inside its?
I have searched a lot in Google, and didn't find answers to my Qs.
Can anyone please help me? Am I on the right way?
Thanks!
If all three independent applications are written with Qt, and you have their source, you should be able to unify them just through the parenting of GUI objects in Qt.
http://qt-project.org/doc/qt-4.8/objecttrees.html
http://qt-project.org/doc/qt-4.8/widgets-and-layouts.html
http://qt-project.org/doc/qt-4.8/mainwindows-mdi.html
If you don't have access to them in that way, what you are talking about is like 3rd party window management. It is kind of like writing a shell, like Windows Explorer, that manipulates the state and the size of other window applications.
Use a program like Spy++ or AutoIt Spy for Windows and the similar ones for other OS's, and learn the identifying markings of your windows you want to control, like the class, the window title, etc. Or you can launch the exe yourself in a QProcess::startDetached() sort of thing.
http://qt-project.org/doc/qt-5.1/qtcore/qprocess.html#startDetached
Then using the OS dependent calls control the windows. The Qt library doesn't have this stuff built in for third party windows, only for ones under the QApplication that you launched. There are a lot of examples of doing things like this by AutoHotKey, or AHK. It is a scripting language that is made for automating a lot of things in the windows environment, and there is port for Mac as well (though I haven't tried the mac port myself).
So in the end you are looking at finding your window probably with a call like this:
#include <windows.h>
HWND hwnd_1 = ::FindWindow("Window_Class", "Window Name");
LONG retVal = GetWindowLongA(hwnd_1, GWL_STYLE); // to query the state of the window
Then manipulate the position and state of the window like so:
::MoveWindow(hwnd_1, x, y, width, height, TRUE);
::ShowWindow(hwnd_1, SW_SHOWMAXIMIZED);
You can even draw widgets on top of the windows you are controlling if you set your window flags correctly for the windows you are manipulating.
transparent QLabel with a pixmap
Cannot get QSystemTrayIcon to work correctly with activation reason
Some gotchas that come up in Windows when doing all of this, is finding out the quirks of the Windows UI when they set the Display scaling different from what you expect, and if you want to play nice with the Task bar, and handling all the modal windows of your programs you are manipulating.
So overall, it is do-able. Qt will make a nice interface for performing these commands, but in the end you are looking at a lot of work and debugging to get it in a beautiful, reliable, window manager.
Hope that helps.
I never tried it myself, but from the docs in Qt 5.1 I would try QWindow::fromId(WId id), which gives you a QWindow, which should be embeddable with createWindowContainer:
QWindow * QWindow::fromWinId(WId id) [static] Creates a local
representation of a window created by another process or by using
native libraries below Qt.
Given the handle id to a native window, this method creates a QWindow
object which can be used to represent the window when invoking methods
like setParent() and setTransientParent(). This can be used, on
platforms which support it, to embed a window inside a container or to
make a window stick on top of a window created by another process.
But no guarantee. :-)

Stealing focus (for a good reason)

I'm working on a clone of Yakuake and, if you have used it, you'd know that one of it's features is stealing the focus for easiness.
Basically, you hit the "show" hotkey, the app appears and you can write on it.
You could be doing whatever thing with whatever app, (being Yakuake hidden), but as soon as you hit the hotkey, Yakuake appears and steals the focus. I want to do the same with my app.
I know there are some window manager rules that prevent applications from doing this, but Yakuake is doing it, why I'm not able to do it?
Also, this application is meant to be compatible with Windows, Linux and Mac, so no KDE or Gnome or < insert_your_favourite_window_manager_here > hacks; I won't go the detect-WM-and-do-hack way.
PS: I'm doing that app in C++ and Qt4.
EDIT:
Just to make it clear, I'm not asking for any code (but if you actually have some example, I appreaciate it). I'm asking for a way for doing it. What should I do to make the WM assign the focus to my app. Is there any standard way for doing so?
There is the Qt::WindowStaysOnTopHint....
The solution is simpler than I thought. I did an animation with a duration of 0s and at the end of the animation I just did a focus. This did the work.
If you want to do it with a "show" hotkey or shortcut you'll have to create and use a hook on the keybord.
Qt don't provide such things so you'll have to do it by yourself.
you can have a look at this post : QT background process
I don't know for other OS.
When you'll get the right keyboard event from your hook, you can create a window with the "allwas on top hint" and that should by ok.

Qt creator, error message

I am a little rusty with QT but I've had to use it for projects before.
I was wondering if I could make a pop-up window, a small window with it's height/width disabled so the user can't expand it. It should also lock the screen until they press a button on this window.
I could do all of this in a separate class, but I was wondering. Are there any built-in QT classes that have a little popup like this that I could just modify? I mean making a class just for an error message seems to me a little wasteful. I'm trying to keep the project small.
But if a class is required to be made in order to accomplish this, that is fine. The only problem is I have no clue how to lock the application windows so that you have to do something one window before you can go back to the main application.
I'm not asking for someone to type out all this code for me, just give me a link or something. I've looked for it but I couldn't find it. Cheers.
QMessageBox messageBox;
messageBox.critical(0,"Error","An error has occured !");
messageBox.setFixedSize(500,200);
The above code snippet will provide the required message box.
For a simple error message, I would suggest you look into the QMessageBox (the documentation contains little example that should show you how to easily achieve what you need), which is modal too. Using a QDialog for displaying a simple error message is possible too, but maybe too much for such a simple task.
I believe what you are looking for is something along the lines of QDialog. Dialogs can be modal or nonmodal. Modal dialogue "block" interaction with the calling window until the Dialog window has been handled.
You can either subclass QDialog or check to see if one of the default dialog classes will be enough for what you need.

Qt and X11 fullscreen application , which blocks Window Manager simultaneously

i think i need to use a XEvent with QMainWindow together to make my application unable to close even by Window Manager , could any one provide an example ?
It's like a fullscreen video game , which blocks all keyboards , mouse buttons.
P.S: QWidget::grabKeyboard() && QWidget::grabMouse() doesn't work when i try to switch to other applications with key combinations like "ALT_TAB"
Thanks.
To completely block all inputs from other apps, you need to use XGrabServer and not XGrabKeyboard/XGrabPointer combination. Dunno whether Qt has an API for that but you can always call the Xlib function directly.
I however recommend against it. If the application is for some reason doesn't release the grab, you're stuck and need to escape to the console to kill it.
I think you can override closeEvent() of your main window and reject the event by using ignore() method as described here.