X11: XQueryPointer gives me fuzzy Windows - c++

I am currently trying to find if one of my Windows is underneath the Mouse cursor. This is not done in my process that creates the window, but in another process.
What I am currently doing is finding the Window via the process PID (and I made sure _NET_WM_PID is set correctly by my program). This basically works via XQueryTree and XGetWindowProperty. This works fine and is not the problem.
The problem is that XQueryPointer gives me fuzzy Windows back. I wrote a simple test program to show what I mean. First gather an ID from any Window you like using the command xprop via bash. It will give you the Window ID.
Then run this simple test program I wrote (quick and dirty), it gives you every 0,5s the current ID from the Window underneath the mouse cursor:
#include <X11/Xlib.h>
#include <iostream>
#include <unistd.h>
#include <stdint.h>
int main()
{
Display *display = XOpenDisplay(0);
Window root = XDefaultRootWindow(display);
Window root_return;
Window child_return;
int root_x_return;
int root_y_return;
int win_x_return;
int win_y_return;
uint32_t mask_return;
while (true)
{
if (::XQueryPointer(display, root, &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &mask_return) == True)
{
std::cout << "Window ID: " << child_return << std::endl;
}
usleep(500000);
}
return 0;
}
Can somebody tell me what the problem is?
And here is my example output:
My program finds Window ID 73400324
xprop finds Window ID 73400324
The test program finds Window ID 20996726

Could be child windows, or the decoration that the window manager adds to a plain window.
By the way, the normal way to detect if your window is under the mouse is by catching the XEnterWindowEvent and XLeaveWindowEvent, but this is normally done within the program itself, not externally.

Related

Why does an error message pause code. and how can you stop the code from pausing at the error message in C++?

Why does a error message in C++ pause the code until the error message is closed out? Here is an example.
#include <iostream>
#include <windows.h>
using namespace std;
int main(){
MessageBox(nullptr, TEXT("Code paused"), TEXT("Code Paused"), MB_OK); // The code pauses at there
cout << "Code unpaused" << endl;
return 0;
}
So why does the code pause at the error box, and how can you stop the code from pausing at the error message?
The MessageBox function designed this way, so that it does not return until message is closed. This design is usually convenient, as it is modal dialog, which means that from user's perspective the state of the program does not change, until the box is closed.
Still, program goes not stop. Other threads execute, and the thread that calls MessageBox also executes and processes messages of all windows (your windows too, not only message box windows).
So you can move message box to a separate thread, move your other code to a separate thread, move your code to a message handler, or write you own MessageBox. Moving your code to a separate thread is the most practical option.
According to MessageBox function:It displays a modal dialog box that contains a system icon, a set of buttons, and a brief application-specific message, such as status or error information.
So it creates a modal dialog box, which means that the user needs to obtain the information returned by the dialog box for further operations.
If you want to make a non-blocking dialog box, I recommend you put it in a separate thread.
Here is the sample:
#include <iostream>
#include <windows.h>
#include <thread>
using namespace std;
void fun()
{
MessageBox(nullptr, TEXT("Code paused"), TEXT("Code Paused"), MB_OK); // The code pauses at there
}
int main() {
thread t(fun);
cout << "Code unpaused" << endl;
t.join();
return 0;
}
If you want to use detach, you need to ensure that the main thread is still working before the child thread ends.
Here is a sample:
#include <iostream>
#include <windows.h>
#include <thread>
using namespace std;
void fun()
{
MessageBox(nullptr, TEXT("Code paused"), TEXT("Code Paused"), MB_OK); // The code pauses at there
}
int main()
{
thread t(fun);
t.detach();
cout << "Code unpaused" << endl;
while (true);
return 0;
}
I added an infinite loop at the end of the main function to ensure that the main thread does not exit. You can use other methods instead.
Here is the output:

Adjust video capture input port using C++ / python

I am having a video capture device (VCD) that acquires frames from a TV which have various output ports (VGA, HDMI, DVI). I read these frames using C++/OpenCV, process them and then show the output on a C++/Qt QLabel.
My problems show up when I change the input port (DVI to HDMI or HDMI to VGA,...), at then I need to manually open the crossbar dialog window for the VCD and switch the input port.
Shows command window with ffmpeg command line + crossbar window for the video capture device
Moreover, for each input port, I need to adjust some parameters relating to color range, scaling size and wire's length.
I need to automate this process of selecting the right input port with the corresponding right parameters using a C++ or python code.
I was searching for a way to read all the input pins of the crossbar dialog box for the video capture device and this set/unset the required pins.
Thanks in advance.
Here is the example in C++/WinAPI how you can set/unset the VIDEO INPUT pins on settings dialog. This code assumes, that checkboxes are children elements of the main dialog; there can be case, when they are nested inside the tab control "Custom settings", so in this case you need find the that tab at first.
#include <windows.h>
#include <string>
#include <vector>
#include <map>
#include <iostream>
int main(int, char **)
{
// Find the dialog
HWND hwnd = FindWindowA(NULL, "%Your settings dialog caption%");
if (hwnd == NULL)
{
std::cerr << "cannot find settings dialog" << std::endl;
return 1;
}
std::map<std::string, HWND> options;
// Get first dialog element
HWND h = GetWindow(hwnd, GW_CHILD);
char caption[250];
std::vector<std::string> inputs{
"1/HDMI",
"2/DVI-D",
"3/COMPONENT",
"DVI",
"4/VGA",
"SOG",
"5/SDI",
"6/COMPOSITE",
"7/S-VIDEO",
"8/AUTO"
};
while (h != NULL)
{
// Get element text
if (GetWindowTextA(h, caption, 250))
{
std::string scaption(caption);
// Check the text, if it's in the list of the option, put it into map.
if (std::find(inputs.begin(), inputs.end(), scaption) != inputs.end())
{
options[caption] = h;
}
}
h = GetWindow(h, GW_HWNDNEXT);
}
// Check the 4/VGA option.
SendMessageA(options["4/VGA"], BM_CLICK, 0, 0);
return 0;
}

Listen close event of iexplorer in my application

I am writing a win32 application by C++, and I want it to do something when all iexplorer.exe were closed.
I know that SetWindowsHook() may be useful in my case.
But if I have no idea about the process or thread ID of IE, because every time open IE would get a different thread ID.
If I do not use timer to check the process list to get the ID of iexplorer, does there have another approach to listen close event of IE in my win32 application?
The object for IE is called InternetExplorer. TheShellWindows object is a collection of InternetExplorer objects. But here it gets complicated. Not all InternetExplorer objects are what you would call an IE window. Some of them are "Windows Explorer" windows. See About the Browser (Internet Explorer).
The following is a managed C++ console program that lists the existing windows and sets a count of the number of existing windows. Then it uses WindowRegistered and WindowRevoked events to monitor creation and closing of windows. Those event are not documented very well. The sample below uses the Document member of each InternetExplorer object to determine if the window has HTML. However see the comment in c# - Distinguishing IE windows from other windows when using SHDocVw; it is possible for a IE window to not have HTML in it.
Note that the following sample is using an AutoResetEvent to keep the program going since it is a console program.
The following is the header:
#pragma once
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <ShlObj.h>
#include <comdef.h>
#include <vcclr.h>
The following is the program:
#include "stdafx.h"
using namespace System;
using namespace System::Threading;
static int Browsers = 0;
static gcroot<AutoResetEvent^> Event;
bool IsBrowser(SHDocVw::InternetExplorer ^ ie)
{
MSHTML::IHTMLDocument2^ Document;
try { Document = (MSHTML::IHTMLDocument2^)ie->Document; }
catch (Exception^ ex)
{
return false;
}
return Document != nullptr;
}
static void WindowRegistered(int lCookie) {
++Browsers;
Console::WriteLine("WindowRegistered");
}
static void WindowRevoked(int lCookie) {
--Browsers;
Console::WriteLine("WindowRevoked");
if (Browsers <= 0)
Event->Set();
}
int main(array<System::String ^> ^args)
{
SHDocVw::ShellWindows^ swList = gcnew SHDocVw::ShellWindowsClass();
Console::WriteLine(L"{0} instances", swList->Count);
for each (SHDocVw::InternetExplorer ^ ie in swList) {
Console::WriteLine(ie->LocationURL);
if (IsBrowser(ie)) {
Console::WriteLine("HTML document");
++Browsers;
}
else
Console::WriteLine("Not HTML");
}
if (Browsers == 0)
{
Console::WriteLine("No browsers");
return 0;
}
Event = gcnew AutoResetEvent(false);
swList->WindowRegistered += gcnew SHDocVw::DShellWindowsEvents_WindowRegisteredEventHandler(WindowRegistered);
swList->WindowRevoked += gcnew SHDocVw::DShellWindowsEvents_WindowRevokedEventHandler(WindowRevoked);
Event->WaitOne();
Console::WriteLine("No more browsers");
return 0;
}
Now I just realized that there is a problem with the way this works. The WindowRegistered and WindowRevoked handlers are incrementing the Browsers count even if the window is not an IE window. I don't know how to determine what window that the cookie passed to WindowRegistered and WindowRevoked represents. A few years ago I spent a couple of days or more tryinig to figure that out. So what you should do is to somehow re-list all the windows after each WindowRegistered and WindowRevoked event.
You need to add references for "Microsoft Internet Controls" (SHDocVw.dll) and "Microsoft HTML Object Library" (mshtml.dll) to the project. They are COM objects that should be in your "C:\Windows\System32" directory.

Creating a standalone gtkmm dialog

In a particular situation I need my command line based C++ application to launch a quick dialog using gtkmm 2.4. I could really use some direction here.
I tried launching the dialog as a standalone without initializing the top level window:
Gtk::Main kit( NULL,NULL );
Gtk::Window toplevel;
MyApp::myDialog d(toplevel);
int result = d.run();
This created my dialog but it doesn't close when the ok or cancel button is hit and none of quit/delete/hide api calls I could find could get rid of it. It only goes away when the program exits (even if it is created in a method which exits earlier). I'm guessing this is in part because it needs an active main window to handle some of its lifetime/visibility management. If I could make it respond normally to the ok/cancel buttons I would be all set!
Next I tried creating and launching the main window properly and launching the dialog from within the constructor of the main window. (It takes the Gtk::Main as an argument so I could try killing that directly.)
class cprompt : public Gtk::Window
{
public:
cprompt(Gtk::Main* prompt){
MyApp::myDialog* d = new MyApp::myDialog (*this);
std::cout << "ABOUT TO RUN DIALOG" << std::endl;
int result = d->run();
std::cout << "RAN DIALOG" << std::endl;
d->hide();
delete d;
std::cout << "CALLING QUIT" << std::endl;
this->hide();
Gtk::Main::quit();
prompt->quit();
//None of the above calls do anything. The empty 'top level' window hangs around and blocks until manually closed.
std::cout << "CALLED QUIT" << std::endl;
};
virtual ~cprompt(){};
};
Now the dialog works as expected, but the main window pops up after the dialog is closed (an empty gray square with an exit button) and I can't find a way to hide or exit it outside of clicking the exit button. All the calls I make to close it or quit the gtk loop automatically are inside the constructor so I'm guessing they aren't valid at that point. If I could make the whole operation shut down after the dialog returns in the window constructor, again I would be all set.
My next approach is going to be to use the top level window itself as the dialog, but I was hoping to avoid this because the dialog I need is already provided by another library and I'll have to re-implement the ui from scratch if I can't launch the dialog straight up.
Had the same problem with Gtk. To fix it, I neeeded to manually close the window and then do the gtk loop iterations. My code looks like this (for a filechooser_dialog) :
gint result = gtk_dialog_run(GTK_DIALOG(m_fileDialog));
if(result == GTK_RESPONSE_ACCEPT)
{
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(m_fileDialog));
m_selectedFileName = std::string(filename);
g_free(filename);
}
gtk_window_close(GTK_WINDOW(m_fileDialog)); //Close the dialog manually
while (gtk_events_pending()) //until there are no more events :
gtk_main_iteration_do(false); //process the main iteration

Controlling Windows Screen Orientation in C++/Qt/Windows

I am looking for a solution to control the screen orientation from within my application.
1. Qt program compiled with visual C++ 2013 (express)
2. Nvidia (if this matters)
I do not just want to control the orientation of the window because this will fail to change the orientation of any onscreen keyboard applications running.
Thank you
This can be done using ChangeDisplaySettings from the windows API
https://msdn.microsoft.com/en-us/library/dd183411%28VS.85%29.aspx
example:
#include <Windows.h>
DEVMODE mode;
//first get setting for "current" screen
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode);
if (mode.dmFields | DM_DISPLAYORIENTATION)
{
mode.dmDisplayOrientation = DMDO_180;
LONG r;
r = ChangeDisplaySettings(&mode, 0);
std::cout << "result: " << r;
}
Look here for info on DEVMODE: https://msdn.microsoft.com/en-us/library/dd183565%28v=vs.85%29.aspx
This can be done using pyautogui.hotkey
from pyautogui import hotkey
hotkey('ctrl','Alt','down')