Which event belongs to window focus changing in qt c++? - c++

I want to save the focused window's title, i made this part but i dont know is there any QEvent which catches all (non-application) focusChanged event? Like switching from Chrome to Qt Creator. I made an alternative solution that checks in every second if the topmost window title has changed but this is so rude. I need cross-platform solution if possible.
EDIT
I am using QT 5.9.0

Quick answer:
Qt only has focus events for it's own windows and widgets. See http://doc.qt.io/qt-5/qfocusevent.html#details for start point.
There is no event for focus in other applications.
Details:
For multi-platform solution is needed to have more general point of view. On some (X window) systems where keyboard focus is in window under mouse. But that window becomes topmost only after click. On Mobile platforms there is only one active application. And application is not allowed seeing when other applications are activated. So in my understanding there is no full multi-platform solution.
Windows only extensions are in the Qt Windows Extras. http://doc.qt.io/qt-5/qtwinextras-overview.html. But there is nothing focus change related unfortunately.

Related

QT - Check if QT app is the app in focus

Here is what I want to do :
Check if my Qt app on windows is an app on the front or minimized.
If its minimized then draw the users attention by making it blink.
Now how can i detect if the app is minimized or on the background ?
I believe this is what you are looking for:
http://qt-project.org/doc/qt-5/qwidget.html#isActiveWindow-prop
then, you can call QWidget::activateWindow().
Looking at the notes:
if you are calling this when the application is not currently the active one then it will not make it the active window. It will change the color of the taskbar entry to indicate that the window has changed in some way.
This sounds exactly like this blink effect you are trying to achieve.
(Links are for Qt5, but this already exists in Qt4: http://qt-project.org/doc/qt-4.8/qwidget.html#activateWindow)

What would be the equivalent to SetForegroundWindow with X11?

I'm part of the SFML Team and we're currently looking into a feature to "request" window focus. The goal is to get very similar behavior across Windows, OS X and Linux.
For Windows one gets the rather simple SetForegroundWindow function via the WinAPI, which has a few condition as to how the window actually gets focus. The most important part to notice here is, that it only gets focus if it's from the same foreground process.
On OS X it's possible to get the focus for the active app only and otherwise let the icon bounce, i.e. notification.
Here comes the problem now, we'd like to get the same behavior on Linux as well, meaning the window should get focus if the window belongs to the active/foreground process and otherwise it should generate a notification. What would be the closest thing to that with X11?
There are already a few suggestions on the issue tracker of SFML, but none of them are actually implementing this behavior.
"User Story"
I guess developers can think of different things when being confronted with different technical names, as such here's the issue from a user perspective.
There are mainly two situations in which requesting focus is needed:
Sometimes when starting an application that uses a console window in the background, it can happen that the console window gets the focus instead of the actual GUI window. When this happens it's rather annoying for the user having to click on the window first. Since the console window and the GUI window are from the same application there's no harm done in switching the focus to the GUI window.
When one is writing an application that supports multiple windows, there might be situations where the application should decide which window gets the focus and again since the window belong to the same application there's no harm done in switching the focus from one GUI window to the other GUI window.
Further more if a different application has the focus/is being used then it's not okay to steal the focus and as such we just want to get the user's attention. For Windows that might be a blinking taskbar or for OS X that might be a jumping icon.
The current implementation seems to work fine on OS X and Windows, butwe're unsure about the X11 implementation. Thus the question is: How would one go about switching the window focus if the currently focussed window has been created by the same application that makes the focus request and otherwise create some kind of notification. For the notification we're/I'm not even sure if there's some generic way of doing it with X11.
In X11, "focus" means "the keyboard focus", that is, the window that gets the keyboard input. The window that has the focus is not necessarily in the foreground. This depends on your window manager focus policy. Most can be configured to have "click-to-focus" or "point-to-focus" policy. If you are interested in the keyboard focus, use XSetInputFocus. If you want to bring your window to the foreground, use XRaiseWindow.
It is OK to call RaiseWindow and XSetInputFocus once, when the application starts. It is also OK to bring a window to the foreground/set focus as a response to a user interaction with that or some other window of the same application. But it's not OK to do so as a response to some background event (time passed, file downloaded etc).
The standard X11 method of drawing attention to a window is setting the urgency hint. This will normally flash or bounce the icon, depending on your window manager. Do not forget to unset the hint when the user finally interacts with the window.
I think all of this has been discussed in the thread you have linked. I'm not quite sure which concerns are still left unanswered. Nothing can implement the exact same behaviour as with the other windowing systems, simply because X11 is not those windowing systems, and it's totally OK. X11, Mac OS X and Windows all behave differently and the users know and expect that. It would annoy me to no end if some application on X11 decided to behave exactly like it does on Windows, instead of toeing the X11 party line.

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. :-)

How to make a taskbar (system tray) application in Windows

The only way I know to launch a windows application is through CreateWindow. Unfortunately, there is not a window style for a taskbar application, and I was wondering how to make a one. I did find this explanation in C#, but I am looking for a solution able to be compiled with VC++ 2008. Any solutions?
The key is Shell_NotifyIcon (as other users suggested).
In a standard scenario your application should have at least one window (at least to receive system tray notification messages). Possibly hidden. On right-click on your tray icon it's a good tone to display a sort of a popoup menu.
I think you may look at this. This simple program demonstrates how to use the system tray in a very minimalistic way.

Qt and native menus

Does Qt support interaction with the native menu bar of an arbitrary window (i. e. QWidget) on Windows and Linux?
It looks like Qt treats the menu as just another child widget to be placed on the parent window. That is, to have a menu bar , I must reserve some space for it in the window's client area. That makes no sense on Mac, with its menu on the top of the screen. On Windows, it makes little sense - the menu, as implemented by the system, is outside of the client area. Not sure what's the native model on Linux.
Qt supports native menues on Mac and on Windows. It may seem when looking at the forms in Qt Designer, that Qt menues on Mac are non-standard, but they aren't. Qt had made a great deal to deal with menue differences between the supported platforms and they work very well.