1

I have created two sets of header and source files which reads the global mouse pointer coordinates (Which Qt5 is unable to) by using the libxdo and it calculates the velocity mathematically and when the velocity of the mouse pointer is above the threshold value, it should display the only Qt window.
The another set of header and source grabs (hook) and listens the global keyboard events and while pressing a key combination, the project runs in the background with the Qt window (after I integrate it with it) being hidden. Whatever I type is being stored in a file until I press [ESC].
Now the Qt window should only appear when I move the mouse pointer above a certain velocity and the text should be shown there.
If while typing I move the mouse, the window should appear and I can see the text that is being written in the QWindow. But when I move the mouse again, it should be hidden.

I'm not using libqxt for qt5 and the above program should run until I logout of the system. Using Ubuntu 16.04.
I'm trying like this in the main.cxx:

#include <QApplication>
#include "mainwindow.hpp"
#include <QDesktopWidget>
#include <QMetaObject>
int main(int argc, char *argv[]) {

    QApplication app(argc, argv);

    MainWindow window;

    int width = QApplication::desktop()->width(), height = QApplication::desktop()->height();

    window.setGeometry ((width - 0.75 * width),height - 20, (width/2) , 10);
    window.setWindowFlags (Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    window.hide();
    QMetaObject::invokeMethod( this, "keygrab", Qt::QueuedConnection, Q_ARG() );
    QMetaObject::invokeMethod( this, "mousevelocity", Qt::QueuedConnection, Q_ARG() );
    return app.exec();
}

But I'm completely messed up with the libx11 and libxdo members and functions inside the mainwindow.cxx of this Qt application and I don't know what will be the best way instead of this or if it is the best, I have a problem as I have multiple main functions with multiple infinite loop for the keygrab and the mousepointer. I can't call them from the main of Qt application and even the above code runs the application first and then invoke them but I need the reverse way. P.S. Sorry, first timer.

xcfg96
  • 23
  • 6
  • What do you mean you have "multiple main functions" ? – SPlatten Dec 06 '17 at 08:57
  • Why so complex? You might use `QCursor::pos()` to get the global mouse coordinates (query it on timer event, for example). – vahancho Dec 06 '17 at 08:59
  • @SPlatten I mean in my keygrab functionality, I have a main function that executes the while loop of keygrabing events and every processing is being called within that while loop. Same I have the main function for the mouse pointer functionality while I tested them individually. Now if I add them along with the qt application as slot, the while loops of the two while never let it to reach to return app.exec() and I think I should run them on separate threads without waiting for a slot to complete first? – xcfg96 Dec 06 '17 at 09:01
  • Are you connecting you slots to any signals? – SPlatten Dec 06 '17 at 09:03
  • @vahancho from the doc, I guess it only shows the coordinates when the mouse pointer is inside that window/widget? – xcfg96 Dec 06 '17 at 09:04
  • @SPlatten No. I'm using the `QMetaObject::invokeMethod` as we can see in the code above – xcfg96 Dec 06 '17 at 09:04
  • @xcfg96 , http://doc.qt.io/qt-5/qcursor.html#pos says it's "...position of the cursor (hot spot) of the primary screen in global screen coordinates". – vahancho Dec 06 '17 at 09:08
  • @vahancho You mean I should start my application window in hidden mode and constantly get and calculate the velocity and if the mouse pointer movement happens above a velocity, I should show the window? But I think it should be run as another thread? Should or can I do muti threading for the same? – xcfg96 Dec 06 '17 at 09:12
  • @xcfg96, You start thinking too complex:) No threads needed at all. You need: 1) Create a class (derived from QObject) with a timer `QTimer` as member variable 2) Connect timer's `timeout()` signal to a slot, where you will get the cursor position and calculate it's speed and show a message when speed exceeds some value 3) Start the timer. – vahancho Dec 06 '17 at 09:17
  • @vahancho I think it won't work on Debian like OS : https://stackoverflow.com/questions/32040202/qt-5-get-the-mouse-position-in-a-screen – xcfg96 Dec 06 '17 at 09:17
  • @xcfg96, well, it may not work. But you can try, at least. – vahancho Dec 06 '17 at 09:19
  • @vahancho Okay I'm trying it. But from the question above, how should I integrate all the background processes (keygrab too) in a single package? Should I call and use them inside the Qt application or should I call another C++ executable from C++ file to achieve so? What should be the best technique? – xcfg96 Dec 06 '17 at 09:23
  • @xcfg96, if you need to use API of another library (libxdo, for example) you should link your application against that library so that when you start your application it will load that library, and you will be able to call its functions. – vahancho Dec 06 '17 at 09:28

1 Answers1

0

I am not 100% sure I get your question, but based on the title of the question and some of the comments, here are some tips:

  1. Qt can know the current global mouse position. Have you googled it? I found the following: QCursor::pos()

  2. For capturing global keyboard events, you will have to give keyboard focus to a widget. There is no way in pure Qt to capture global keyboard events otherwise. I presume you could do this by having a small transparent QWidget that gives itself keyboard focus in a loop, and then never capturing any of the events (so they get passed along to other programs), but I never tested so YMMV.

  3. To create a "system level background routine", you will have to start a daemon process. To do this I can recommend looking at documentation and examples of QProcess & friends. Basically what you do ay startup of you app, the app starts a second instance of itself using a special command line parameter that tell that second child process to go in the background. Then the parent process will quit, leaving the child process behind running in the background.

  4. This daemon will run whatever code it needs in an event loop which is the way of Qt programs. Whenever it receives a noteworthy event, you can process and act on those events to your heart's content. If you need to get events from non-Qt contexts, simply create a QTimer and poll whatever interface you need for events.

  5. Once an event occurs, you can show a QWidgets at the exact position you want on the screen (howto here).

  6. Once your daemon process works, the next is figuring out how to deploy it. Most daemons need to be installed as services into the OS for them to be reliably started on boot. Each window environment may have their own provisioning of such "run until logout" deployments. If you are feeling especially fancy, the program intself may do the deployment routine needed before it forks, which makes it plug-and-play.

Mr. Developerdude
  • 9,118
  • 10
  • 57
  • 95