Could someone help me making movable undecorated window?


#1

yj1214 wrote on Tuesday, September 15, 2015:

I’m trying to make my undecorated window movable and resizable but I can’t figure out how to make my window movable.

This is what I so far have,

CODE EDITED

#include <stdio.h>
#include <math.h>
#include <GL/gl.h>
#include "include/GLFW/glfw3.h"

void cursor_position_callback(GLFWwindow* window, double x, double y);
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods);

int cp_x;
int cp_y;
int wrel_cpx;
int wrel_cpy;
int w_posx;
int w_posy;
int buttonEvent;

int main(){
    glfwInit();
    glfwWindowHint(GLFW_DECORATED, 0);
    GLFWwindow *window = glfwCreateWindow(640, 480, "Undecorated Resizable", 0, 0);

    glfwSetCursorPosCallback(window, cursor_position_callback);
    glfwSetMouseButtonCallback(window, mouse_button_callback);

    glfwMakeContextCurrent(window);


    while(!glfwWindowShouldClose(window)){
        if(buttonEvent == 1){
            glfwSetWindowPos(window, wrel_cpx - cp_x, wrel_cpy - cp_y);
        }

        glfwSwapBuffers(window);

        glfwWaitEvents();
    }

    return 0;
}

void cursor_position_callback(GLFWwindow* window, double x, double y){
    glfwGetWindowPos(window, &w_posx, &w_posy);
    wrel_cpx = cp_x + w_posx;
    wrel_cpy = cp_y + w_posy;
    cp_x = floor(x);
    cp_y = floor(y);
}

void mouse_button_callback(GLFWwindow* window, int button, int action, int mods){
    if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS){
        buttonEvent = 1;
    }
    if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE){
        buttonEvent = 0;
    }
}

When I try to drag my window, it does absoutely nothing. Its position stays the same.

Could someone please help me?


#2

genusis wrote on Saturday, November 07, 2015:

To do the above you will need to get the cursor position, where you last clicked and if the mouse button is still down. If the mouse is down while the cursor is moving then have something like

int winx, winy;

glfwGetWindowPos(window->screen, &winx, &winy);
glfwSetWindowPos(screen, mouse.x + winx - mouse_clicked.x, mouse.y + winy - mouse_clicked.y);

IF you want to simplfy this process and have a ok GUI like setup or something to learn from or need more help feel free to ask me or go to http://ascendingcreations.com/

IF you do want the GUI like system which uses GLFW feel free to take a look at it here


#3

Hey, Thanks for the solution. I did the same by the way. But there is a shake when I move windows.

void Window::mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
    Window* winClass = (Window*)glfwGetWindowUserPointer(window);
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
      winClass->mClicked = true;
      double xpos, ypos;
      glfwGetCursorPos(window, &(xpos), &(ypos));
      glfwGetWindowPos(window, &(winClass->mWinX), &(winClass->mWinY));
      winClass->mMouseX = xpos + winClass->mWinX;
      winClass->mMouseY = ypos + winClass->mWinY;
    }
    if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE)
      winClass->mClicked = false;
  }

  void Window::mouse_movement_callback(GLFWwindow* window, double x, double y) {
    Window* winClass = (Window*)glfwGetWindowUserPointer(window);
    if (winClass->mClicked) {
      int xpos, ypos; /// MARK #1
      glfwGetWindowPos(window,&xpos, &ypos);
      x += xpos;
      y += ypos;
      // std::cout << "Stored.Mouse : (" << winClass->mMouseX << ", " << winClass->mMouseY << ")" <<
      //   "Stored.Window : (" << xpos << ", " << ypos << ")"<<std::endl;
      std::cout << x << " - " << winClass->mMouseX << " = " << x - winClass->mMouseX << "," <<
        y << " - " << winClass->mMouseY << " = " << y - winClass->mMouseY << std::endl;
      int finalx = winClass->mWinX + (x - winClass->mMouseX);
      int finaly = winClass->mWinY + (y - winClass->mMouseY);
      glfwSetWindowPos(window,finalx, finaly);
     }
    //std::cout << "Mouse Pos : " << x << ", " << y << std::endl;
  }

  void Window::window_resize_callback(GLFWwindow* window, int width, int height) {
    Window* winClass = (Window*)glfwGetWindowUserPointer(window);

    winClass->setSize(Size{uint(width), uint(height)});
    Size s = winClass->getSize();
    std::cout << "Resized : " << s.Width << ", " << s.Height << std::endl;
  }

This is a part of my code. Am I doing something wrong? For some reason the variables at MARK #1 (xpos and ypos) in Window::mouse_movement_callback in the if clause, are erratic when rapid movements are made.

663 - 254 = 409,210 - 118 = 92
660 - 254 = 406,228 - 118 = 110
667 - 254 = 413,231 - 118 = 113
673 - 254 = 419,232 - 118 = 114
713 - 254 = 459,265 - 118 = 147
718 - 254 = 464,265 - 118 = 147
758 - 254 = 504,277 - 118 = 159
761 - 254 = 507,279 - 118 = 161
807 - 254 = 553,294 - 118 = 176
765 - 254 = 511,263 - 118 = 145
729 - 254 = 475,234 - 118 = 116
732 - 254 = 478,236 - 118 = 118
734 - 254 = 480,237 - 118 = 119
700 - 254 = 446,229 - 118 = 111
703 - 254 = 449,230 - 118 = 112
705 - 254 = 451,251 - 118 = 133
708 - 254 = 454,252 - 118 = 134
745 - 254 = 491,283 - 118 = 165
748 - 254 = 494,284 - 118 = 166
749 - 254 = 495,263 - 118 = 145
790 - 254 = 536,275 - 118 = 157
793 - 254 = 539,276 - 118 = 158
799 - 254 = 545,280 - 118 = 162
802 - 254 = 548,281 - 118 = 163
771 - 254 = 517,275 - 118 = 157
774 - 254 = 520,275 - 118 = 157
740 - 254 = 486,265 - 118 = 147
743 - 254 = 489,267 - 118 = 149
712 - 254 = 458,258 - 118 = 140
715 - 254 = 461,259 - 118 = 141
718 - 254 = 464,261 - 118 = 143
787 - 254 = 533,282 - 118 = 164
789 - 254 = 535,282 - 118 = 164
858 - 254 = 604,302 - 118 = 184
857 - 254 = 603,300 - 118 = 182

This is the output of the program. If you see the values to the far left (xpos) it is variadic even though my mouse movement is in the same diagonal direction


#4

I’ve not tried this with GLFW, but here’s some thoughts / questions:

  1. What cursor mode are you using? It looks like you may be using a non GLFW_CURSOR_DISABLED mode.
  2. The standard cursor callback position is relative to the top-left corner of the window client area so as you move the window under the cursor you should see it stay constant.
  3. It’s possible that your window position and mouse movement events are not in sync - for example the system may have queued mouse movement events based on the old window position.Tracking the window position event through a callback might help correct that.

The later two items could explain what you’re seeing - I expect that every time your see the mouse position go backwards it’s because you’re seeing a lagged update of the window position. You either need to use a disabled cursor for virtual coordinates or use the position callback to modify the window offset mWinX and mWinY.


#5

Actually I figured out what happened. In yours it is the third one. I didnt have glfwWaitEvents in the main loop thus all queued events are getting called when I make a fast movement.


Thanks Anyway