Commit 293a9c20 by Jessica Hawkwell

yay moving windows

1 parent eb0befb4
/*
* Copyright(c) 2018, jlhawkwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NPOSITION_H
#define NPOSITION_H
#include <string>
template <typename T>
class NPosition
{
protected:
T px;
T py;
public:
NPosition<T>(T x, T y) {
px = x;
py = y;
}
NPosition<T>(const NPosition<T>& other) {
px = other.px;
py = other.py;
}
NPosition<T>& operator=(const NPosition<T>& other) {
px = other.px;
py = other.py;
return *this;
}
NPosition<T> operator+(const NPosition<T>& other) {
NPosition<T> rt = NPosition<T>(px + other.px, py + other.py);
return rt;
}
NPosition<T> operator-(const NPosition<T>& other) {
NPosition<T> rt = NPosition<T>(px - other.px, py - other.py);
return rt;
}
bool operator==(const NPosition<T>& other) const {
if (px != other.getX()) { return false; }
if (py != other.getY()) { return false; }
return true;
}
std::string toString() {
std::string out = std::string();
out.append("(");
out.append(std::to_string(px));
out.append(", ");
out.append(std::to_string(py));
out.append(")");
return out;
}
T getX() { return px; }
T getY() { return py; }
void setZeroIfNegative() {
if (px < 0) { px = 0; }
if (py < 0) { py = 0;}
}
};
#endif // NPOSITION_H
/*
* Copyright(c) 2018, jlhawkwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NSIZE_H
#define NSIZE_H
template <class T>
class NSize
{
protected:
T pwidth;
T pheight;
public:
NSize<T>(T width, T height) {
pwidth = width;
pheight = height;
}
NSize<T>(const NSize<T>& other) {
pwidth = other.pwidth;
pheight = other.pheight;
}
NSize<T>& operator=(const NSize<T>& other) {
pwidth = other.pwidth;
pheight = other.pheight;
return *this;
}
bool operator==(const NSize<T>& other) const {
if (pwidth != other.getWidth()) { return false; }
if (pheight != other.getHeight()) { return false; }
return true;
}
T getWidth() { return pwidth; }
T getHeight() { return pheight; }
};
#endif // NSIZE_H
...@@ -54,12 +54,10 @@ void NUtils::frameWindow (Window w, bool pre_exist) { ...@@ -54,12 +54,10 @@ void NUtils::frameWindow (Window w, bool pre_exist) {
(*NWMAction::clients)[w] = frame; (*NWMAction::clients)[w] = frame;
XGrabButton(NWMAction::disp, Button1, Mod1Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(NWMAction::disp, Button1, Mod1Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(NWMAction::disp, Button1, Mod2Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(NWMAction::disp, Button1, Mod1Mask | Mod2Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(NWMAction::disp, Button1, Mod3Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(NWMAction::disp, Button3, Mod1Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(NWMAction::disp, Button1, Mod4Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); XGrabButton(NWMAction::disp, Button3, Mod1Mask | Mod2Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(NWMAction::disp, Button1, Mod5Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None); }
XGrabButton(NWMAction::disp, Button2, Mod4Mask, w, false, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, GrabModeAsync, GrabModeAsync, None, None);
}
void NUtils::unFrameWindow (Window w) { void NUtils::unFrameWindow (Window w) {
......
...@@ -34,9 +34,18 @@ ...@@ -34,9 +34,18 @@
#include "NWMAction.h" #include "NWMAction.h"
#include "NUtils.h" #include "NUtils.h"
#include <iostream> #include <iostream>
#include <vector>
// MOVING WINDOWS
NPosition<int> *NWMAction::drag_start_cursor;
NPosition<int> *NWMAction::drag_start_window;
NSize<unsigned int> *NWMAction::drag_start_resize;
// XLIB
Display *NWMAction::disp; Display *NWMAction::disp;
Window *NWMAction::root; Window *NWMAction::root;
// WINDOWS
std::unordered_map<Window, Window> *NWMAction::clients; std::unordered_map<Window, Window> *NWMAction::clients;
void NWMAction::onKeyPress(XKeyPressedEvent e) { void NWMAction::onKeyPress(XKeyPressedEvent e) {
...@@ -48,7 +57,34 @@ void NWMAction::onKeyRelease(XKeyReleasedEvent e) { ...@@ -48,7 +57,34 @@ void NWMAction::onKeyRelease(XKeyReleasedEvent e) {
} }
void NWMAction::onButtonPress(XButtonPressedEvent e) { void NWMAction::onButtonPress(XButtonPressedEvent e) {
if (!clients->count(e.window)) { return; }
if (drag_start_cursor == nullptr) {
drag_start_cursor = new NPosition<int>(e.x_root, e.y_root);
}
else {
*drag_start_cursor = NPosition<int>(e.x_root, e.y_root);
}
int x = 0, y = 0;
unsigned int w = 0, h = 0;
unsigned int bw = 0, depth = 0;
Window frame = (*clients)[e.window];
Window *rroot;
XGetGeometry(disp, frame, rroot, &x, &y, &w, &h, &bw, &depth);
if (drag_start_window == nullptr) {
drag_start_window = new NPosition<int>(x, y);
}
else {
*drag_start_window = NPosition<int>(x, y);
}
if (drag_start_resize == nullptr) {
drag_start_resize = new NSize<unsigned int>(w, h);
}
else {
*drag_start_resize = NSize<unsigned int>(w, h);
}
XRaiseWindow(disp, frame);
} }
void NWMAction::onButtonRelease(XButtonReleasedEvent e) { void NWMAction::onButtonRelease(XButtonReleasedEvent e) {
...@@ -56,13 +92,39 @@ void NWMAction::onButtonRelease(XButtonReleasedEvent e) { ...@@ -56,13 +92,39 @@ void NWMAction::onButtonRelease(XButtonReleasedEvent e) {
} }
void NWMAction::onMotionNotify(XMotionEvent e) { void NWMAction::onMotionNotify(XMotionEvent e) {
if (!(*clients).count(e.window)) { return; } if (!clients->count(e.window)) { return; }
std::cout << "XMotionEvent: " << e.window; std::cout << "XMotionEvent: " << e.window;
std::cout << " (" << e.x << ", " << e.y << "), ("; std::cout << " (" << e.x << ", " << e.y << "), (";
std::cout << e.x_root << ", " << e.y_root << ")"; std::cout << e.x_root << ", " << e.y_root << ") ";
std::cout << e.state;
if (e.state & Button1Mask) { std::cout << " Button1Mask"; }
if (e.state & Button2Mask) { std::cout << " Button2Mask"; }
if (e.state & Button3Mask) { std::cout << " Button3Mask"; }
if (e.state & Button4Mask) { std::cout << " Button4Mask"; }
if (e.state & Button5Mask) { std::cout << " Button5Mask"; }
if (e.state & ShiftMask) { std::cout << " ShiftMask"; }
if (e.state & LockMask) { std::cout << " LockMask"; }
if (e.state & ControlMask) { std::cout << " ControlMask"; }
if (e.state & Mod1Mask) { std::cout << " Mod1Mask"; }
if (e.state & Mod2Mask) { std::cout << " Mod2Mask"; }
if (e.state & Mod3Mask) { std::cout << " Mod3Mask"; }
if (e.state & Mod4Mask) { std::cout << " Mod4Mask"; }
if (e.state & Mod5Mask) { std::cout << " Mod5Mask"; }
std::cout << std::endl; std::cout << std::endl;
Window frame = (*clients)[e.window];
NPosition<int> drag_pos(e.x_root, e.y_root);
NPosition<int> delta = drag_pos - *drag_start_cursor;
if (e.state & Button1Mask) { // move window
std::cout << "\tDelta: " << delta.toString() << std::endl;
NPosition<int> dest = delta + *drag_start_window;
dest.setZeroIfNegative();
XMoveWindow(disp, frame, dest.getX(), dest.getY());
}
} }
void NWMAction::onEnterNotify(XEnterWindowEvent e) { void NWMAction::onEnterNotify(XEnterWindowEvent e) {
...@@ -154,7 +216,7 @@ void NWMAction::onConfigureRequest(XConfigureRequestEvent e) { ...@@ -154,7 +216,7 @@ void NWMAction::onConfigureRequest(XConfigureRequestEvent e) {
} }
XConfigureWindow(disp, e.window, e.value_mask, &changes); XConfigureWindow(disp, e.window, e.value_mask, &changes);
} }
void NWMAction::onGravityNotify(XGravityEvent e) { void NWMAction::onGravityNotify(XGravityEvent e) {
...@@ -209,7 +271,7 @@ void NWMAction::onLASTEvent(XAnyEvent e) { ...@@ -209,7 +271,7 @@ void NWMAction::onLASTEvent(XAnyEvent e) {
} }
void NWMAction::onDefaultEvent(XAnyEvent e) { void NWMAction::onDefaultEvent(XAnyEvent e) {
std::cout << "Event [" << NUtils::getEventName(e.type) << "] on"; std::cout << "Event [" << NUtils::getEventName(e.type) << "] on ";
std::cout << e.window << " @ " << e.display << std::endl; std::cout << e.window << " @ " << e.display << std::endl;
} }
...@@ -35,14 +35,28 @@ ...@@ -35,14 +35,28 @@
#define NWMACTION_H #define NWMACTION_H
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <vector>
#include <unordered_map> #include <unordered_map>
# include "NPosition.h"
# include "NSize.h"
class NWMAction { class NWMAction {
protected:
// MOVING WINDOWS
static NPosition<int> *drag_start_cursor;
static NPosition<int> *drag_start_window;
static NSize<unsigned int> *drag_start_resize;
public: public:
// XLIB
static Display *disp; static Display *disp;
static Window *root; static Window *root;
// WINDOWS
static std::unordered_map<Window, Window> *clients; static std::unordered_map<Window, Window> *clients;
// EVENT METHODS
static void onKeyPress(XKeyPressedEvent e); static void onKeyPress(XKeyPressedEvent e);
static void onKeyRelease(XKeyReleasedEvent e); static void onKeyRelease(XKeyReleasedEvent e);
static void onButtonPress(XButtonPressedEvent e); static void onButtonPress(XButtonPressedEvent e);
......
...@@ -65,6 +65,14 @@ int NWManager::OnWMDetected(Display *display, XErrorEvent *e) { ...@@ -65,6 +65,14 @@ int NWManager::OnWMDetected(Display *display, XErrorEvent *e) {
int NWManager::OnXError(Display *display, XErrorEvent *e) { int NWManager::OnXError(Display *display, XErrorEvent *e) {
const int MAX_ERROR_TEXT_LENGTH = 1024;
char error_text[MAX_ERROR_TEXT_LENGTH];
XGetErrorText(display, e->error_code, error_text, sizeof(error_text));
std::cerr << "Received X error:" << std::endl
<< " Request: " << int(e->request_code) << std::endl
<< " Error code: " << int(e->error_code)
<< " - " << error_text << std::endl
<< " Resource ID: " << e->resourceid << std::endl;
return 0; return 0;
} }
...@@ -110,7 +118,7 @@ void NWManager::run() { ...@@ -110,7 +118,7 @@ void NWManager::run() {
switch (e.type) { switch (e.type) {
//case KeyPress: break; //case KeyPress: break;
//case KeyRelease: break; //case KeyRelease: break;
//case ButtonPress: break; case ButtonPress: NWMAction::onButtonPress(e.xbutton); break;
//case ButtonRelease: break; //case ButtonRelease: break;
case MotionNotify: NWMAction::onMotionNotify(e.xmotion); break; case MotionNotify: NWMAction::onMotionNotify(e.xmotion); break;
//case EnterNotify: break; //case EnterNotify: break;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#ifndef NWMANAGER_H #ifndef NWMANAGER_H
#define NWMANAGER_H #define NWMANAGER_H
#include <X11/X.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <unordered_map> #include <unordered_map>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!