How do I track move event for all the windows?
Like if user moves window "Pluma" my daemon would receive window name and new coordinates.
if(XCheckMaskEvent(display, -1, &event))
{
if(event.type == ConfigureNotify)
{
moved += event.xmotion.x + event.xmotion.y;
//qDebug << moved;
}
}
I tried tracking it like this, but it does not work...
You need t select SubstructureNotify mask on the root window first:
XSelectInput(display, XDefaultRootWindow(display), SubstructureNotifyMask );
This way you are telling X server "I'm interested in root window childrens move/resize/delete/create events"
Related
I am using arch linux and a basic cpp xlib custom window manager. However, every time I right click to open the context menu it just flickers and disappears. I cannot use it at all. I also cannot use top drop down menus (file, edit, about, ect.) on any application. Is there anything in Xlib which I have to look out for to ensure I may use the context menus normally?
This is the case in every application I have tried. Only clue I have is in brave it occasionally displays the following message:
XGetWindowAttributes failed for window [WINDOW_ID]
The following simplified example also has this issue:
int main()
{
display = XOpenDisplay(nullptr);
root = DefaultRootWindow(display);
XSelectInput(display, root, SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask);
XGrabServer(display);
Window returned_root;
Window returned_parent;
Window* top_level_windows;
unsigned int num_top_level_windows;
XQueryTree(display, root, &returned_root, &returned_parent, &top_level_windows, &num_top_level_windows);
for(unsigned int i = 0; i < num_top_level_windows; ++i)
{
Frame(top_level_windows[i], true);
}
XFree(top_level_windows);
XUngrabServer(display);
for(;;)
{
XEvent event;
XNextEvent(display, &event);
switch (event.type)
{
case MapRequest:
{
Frame(event.xmaprequest.window, false);
XMapWindow(display, event.xmaprequest.window);
break;
}
case ButtonPress:
XRaiseWindow(display, event.xbutton.window);
break;
}
}
return true;
}
void Frame(Window window, bool created_before_manager)
{
//Retrieve attributes of window to frame
XWindowAttributes attr = {0};
XGetWindowAttributes(display, window, &attr);
//If window was created before window manager started, we should frame it only if it is visible and does not set override_redirect
if(created_before_manager && (attr.override_redirect || attr.map_state != IsViewable))
{
return;
}
//Create frame
Window frame = XCreateSimpleWindow(display, root, attr.x, attr.y, attr.width, attr.height, 5, 0xff0000, 0xffffff);
XReparentWindow(display, window, frame, 0, 0);
XMapWindow(display, frame);
XGrabButton(display, Button1Mask, Mod1Mask, window, None, ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None);
}
To be clear it also works with a super simple example such as:
int main()
{
Display* display = XOpenDisplay(nullptr);
for(;;) {}
return true;
}
The reason I believe the window manager is at fault is because this issue only occurs after I run the window manager.
I expected this to work out of the box. I have not found any information on context menus needing special treatment. They do have the override_redirect flag set to true, so I do not frame them. I cannot find information on any other special treatment required.
It is necessary to make sure the client window has input. I had the input set to whatever was clicked (frame, title bar, or client) because it worked fine as far as normal input is concerned. However, the context menus will only work if you make sure the input is set to the client window directly.
I'm trying to implement a feature that changes the color of a child window when the user hovers over it. To do this, I need to receive EnterNotify events for specific child windows. I'm getting the EnterNotify events with no problem, but I can't figure out how to distinguish between which child window the EnterNotify event is coming from. How do I get the event window from an event?
if (event.type == EnterNotify && event.xcrossing.window == w11) {
std::cout << "ENTER WINDOW" << std::endl;
}
This is what I have tried with w11 being the child window. Nothing is sent to output when the EnterNotify events come in, but if I change the event.xcrossing.window equivalency to win (the parent window), as shown below, it will produce output as the EnterNotify events roll in. Thanks.
if (event.type == EnterNotify && event.xcrossing.window == win) {
std::cout << "ENTER WINDOW" << std::endl;
}
It turns out that when you create a child window using XCreateSimpleWindow, the parent window's mask input is not carried over to the child window. All I had to do was update each child window to receive EnterWindowMask events.
So basically am learning OpenGL and the GLFW libraries from the tutorial on page: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-6-keyboard-and-mouse/
My problems is with this less lesson showing the control of camera movement with mouse.
Basicaly it makes the application to get "FPS" like camera, with disabled cursor being moved on center of screen with each frame. But the camera gets crazy when we lose focus on the window and then it regains. For example if we click on the window to regain focus away from the middle of view, the camera will be moved by big amount. I tried to fix this issue with adding window focus callback:
void window_focus_callback(GLFWwindow* window, int focused){
if (focused)
{
//center mouse on screen
int width, height;
glfwGetWindowSize(window, &width, &height);
glfwSetCursorPos(window, 1024 / 2, 768 / 2);
windowFocused = true;
}
else
{
windowFocused = false;
}
And in the main application loop:
if(windowFocused) computeMatricesFromInputs();
But for some reason this solution doesnt work.
Is there any way to fix this issue using glfw?
Question is a bit old, but I recently suffered a similar issue. So just sharing, more solutions exist.
I use GLFW_CURSOR_DISABLED. In this mode the mouse position is not (yet) updated when you receive the 'on' focus event, so call to GetCursorPos delivers the previous value. The new cursor position arrives in the MouseMove callback AFTER the 'on' focus event.
I solved it by keeping track of the regain of focus and use this int he OnMouseMove callback to either dispatch a MouseInit (to snap the cursor) or a regular MouseMove.
This way I can ALT+TAB out of my window and return with the cursor somewhere else without nasty jumps/rotations of the camera.
void InputManagerGLFW::Callback_OnMouseMove(
GLFWwindow* window,
double xpos, //
double ypos) //
{
if (!mFocusRegained)
{
mMouseBuffer.Move(xpos, ypos);
}
else
{
mFocusRegained = false;
mMouseBuffer.Init(xpos, ypos);
}
}
void InputManagerGLFW::Callback_OnFocus(
GLFWwindow* window,
int focused)
{
if (focused)
{
// The window gained input focus
// Note: the mouse position is not yet updated
// the new position is provided by the mousemove callback AFTER this callback
Log::Info("focus");
// use flag to indicate the OnMouseMove that we just regained focus,
// so the first mouse move must be handled differently
mFocusRegained = true;
// this will NOT work!!!
// double x,y;
// glfwGetCursorPos(window,&x,&y);
// mMouseBuffer.Init(x,y);
}
else
{
// The window lost input focus
Log::Info("focus lost");
}
}
In SDL2 when you resize the window by dragging the corners during runtime, a window resized event is triggered and can be used like this:
SDL_Event e;
int width, height;
SDL_PollEvent(&e);
if(e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_RESIZED)
{
width = e.window.data1;
height = e.window.data2;
}
If I resize a window manually like this:
SDL_SetWindowSize(window, myWidth, myHeight);
(documentation)
Will this trigger a window event like above?
Yes, just like SDL_SetWindowFullscreen (). SDL_SetWindowSize () triggers window events. Technically, I think it just resizes the window, which is treated as if the user manually resized it.
Using SDL_WINDOWEVENT_RESIZED, the answer is no. But an SDL_WINDOWEVENT_SIZE_CHANGED event is triggered.
I have a qt application, window with several child widgets that are Qt::Tool windows.
When I minimize window and then restore on windows 7 child widgets appear immediately, but parent window not because of animation.
Is there any way to prevent this behavior and make child windows appear after main window?
Why don't you hide the tool windows while the main window is restoring? You can use this piece of code and adapt it to your needs:
void MainWindow::changeEvent( QEvent* e )
{
if ( e->type() == QEvent::WindowStateChange )
{
QWindowStateChangeEvent* event =
static_cast< QWindowStateChangeEvent* >( e );
if ( event->oldState() & Qt::WindowMinimized ) {
qDebug() << "The Window has been restored!";
}
else if ( (event->oldState() == Qt::WindowNoState) &&
(this->windowState() == Qt::WindowMaximized) ) {
qDebug() << "the window has been Maximized!";
}
}
}
For example, you can start a timer for a certain amount of time, and have the slot connected to your child tool windows, making them appear as you wish.
You can also play with transparency in the child tool windows, and emulate the main window effects.
As I recall, something like this will do:
setStyleSheet("background:transparent;");
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::FramelessWindowHint);
Hope that helped!