mirror of
https://github.com/hyprwm/Hypr.git
synced 2024-11-22 13:35:57 +01:00
initial commit, very simple and buggy prolly :)
This commit is contained in:
parent
efb783c97c
commit
53a64d9574
18 changed files with 555 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -9,3 +9,6 @@ install_manifest.txt
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
_deps
|
_deps
|
||||||
|
|
||||||
|
build/
|
||||||
|
.vscode/
|
24
CMakeLists.txt
Normal file
24
CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
cmake_minimum_required(VERSION 3.4)
|
||||||
|
project(Hypr
|
||||||
|
VERSION 0.1
|
||||||
|
DESCRIPTION "A Modern OOP C++ Window Manager"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_compile_options(-std=c++17)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE SRCFILES "src/*.cpp")
|
||||||
|
|
||||||
|
add_executable(Hypr ${SRCFILES})
|
||||||
|
|
||||||
|
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||||
|
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||||
|
include(CPack)
|
||||||
|
|
||||||
|
target_link_libraries(Hypr
|
||||||
|
xcb
|
||||||
|
xcb-ewmh
|
||||||
|
xcb-icccm
|
||||||
|
xcb-keysyms
|
||||||
|
xcb-randr
|
||||||
|
xcb-xinerama
|
||||||
|
)
|
|
@ -1,2 +1,4 @@
|
||||||
# Hypr
|
# Hypr
|
||||||
Hypr is a tiling window manager written in modern OOP C++
|
Hypr is a tiling window manager written in modern OOP C++
|
||||||
|
|
||||||
|
I will make this readme better in the future cant be arsed to do it rn
|
10
src/KeybindManager.cpp
Normal file
10
src/KeybindManager.cpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#include "KeybindManager.hpp"
|
||||||
|
|
||||||
|
Keybind* KeybindManager::findKeybindByKey(int mod, xcb_keysym_t keysym) {
|
||||||
|
for(auto& key : KeybindManager::keybinds) {
|
||||||
|
if (keysym == key.getKeysym() && mod == key.getMod()) {
|
||||||
|
return &key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
11
src/KeybindManager.hpp
Normal file
11
src/KeybindManager.hpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "utilities/Keybind.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace KeybindManager {
|
||||||
|
std::vector<Keybind> keybinds;
|
||||||
|
|
||||||
|
|
||||||
|
// -- Methods -- //
|
||||||
|
|
||||||
|
Keybind* findKeybindByKey(int mod, xcb_keysym_t keysym);
|
||||||
|
};
|
24
src/defines.hpp
Normal file
24
src/defines.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "./helpers/Vector.hpp"
|
||||||
|
|
||||||
|
#include "./utilities/Debug.hpp"
|
||||||
|
|
||||||
|
#define EXPOSED_MEMBER(var, type, prefix) \
|
||||||
|
private: \
|
||||||
|
type m_##prefix##var; \
|
||||||
|
public: \
|
||||||
|
type get##var() { return this->m_##prefix##var; } \
|
||||||
|
void set##var(type value) { this->m_##prefix##var = value; }
|
||||||
|
|
||||||
|
|
||||||
|
#define EVENT(name) \
|
||||||
|
void event##name(xcb_generic_event_t* event);
|
||||||
|
|
||||||
|
#define STICKS(a, b) abs(a - b) < 2
|
56
src/events/events.cpp
Normal file
56
src/events/events.cpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#include "events.hpp"
|
||||||
|
|
||||||
|
void Events::eventEnter(xcb_generic_event_t* event) {
|
||||||
|
const auto E = reinterpret_cast<xcb_enter_notify_event_t*>(event);
|
||||||
|
|
||||||
|
// Just focus it and update.
|
||||||
|
WindowManager::setFocusedWindow(E->event);
|
||||||
|
|
||||||
|
// vvv insallah no segfaults
|
||||||
|
WindowManager::getWindowFromDrawable(E->event)->setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::eventDestroy(xcb_generic_event_t* event) {
|
||||||
|
const xcb_destroy_notify_event_t* E = reinterpret_cast<xcb_destroy_notify_event_t*>(event);
|
||||||
|
xcb_kill_client(WindowManager::DisplayConnection, E->window);
|
||||||
|
|
||||||
|
// fix last window
|
||||||
|
const auto CLOSEDWINDOW = WindowManager::getWindowFromDrawable(E->window);
|
||||||
|
if (CLOSEDWINDOW) {
|
||||||
|
WindowManager::fixWindowOnClose(CLOSEDWINDOW);
|
||||||
|
|
||||||
|
// delete off of the arr
|
||||||
|
WindowManager::removeWindowFromVectorSafe(E->window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Events::eventMapWindow(xcb_generic_event_t* event) {
|
||||||
|
const xcb_map_request_event_t* E = reinterpret_cast<xcb_map_request_event_t*>(event);
|
||||||
|
|
||||||
|
// Map the window
|
||||||
|
xcb_map_window(WindowManager::DisplayConnection, E->window);
|
||||||
|
|
||||||
|
// Do the setup of the window's params and stuf
|
||||||
|
CWindow window;
|
||||||
|
window.setDrawable(E->window);
|
||||||
|
window.setIsFloating(false);
|
||||||
|
window.setDirty(true);
|
||||||
|
|
||||||
|
// Also sets the old one
|
||||||
|
WindowManager::calculateNewWindowParams(&window);
|
||||||
|
|
||||||
|
// Focus
|
||||||
|
WindowManager::setFocusedWindow(E->window);
|
||||||
|
|
||||||
|
// Add to arr
|
||||||
|
WindowManager::addWindowToVectorSafe(window);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Created a new window! X: " + std::to_string(window.getPosition().x) + ", Y: " + std::to_string(window.getPosition().y) + ", W: "
|
||||||
|
+ std::to_string(window.getSize().x) + ", H:" + std::to_string(window.getSize().y) + " ID: " + std::to_string(E->window));
|
||||||
|
|
||||||
|
// Set map values
|
||||||
|
WindowManager::Values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE;
|
||||||
|
xcb_change_window_attributes_checked(WindowManager::DisplayConnection, E->window, XCB_CW_EVENT_MASK, WindowManager::Values);
|
||||||
|
|
||||||
|
WindowManager::setFocusedWindow(E->window);
|
||||||
|
}
|
8
src/events/events.hpp
Normal file
8
src/events/events.hpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "../defines.hpp"
|
||||||
|
#include "../windowManager.hpp"
|
||||||
|
|
||||||
|
namespace Events {
|
||||||
|
EVENT(Enter);
|
||||||
|
EVENT(Destroy);
|
||||||
|
EVENT(MapWindow);
|
||||||
|
};
|
19
src/helpers/Vector.cpp
Normal file
19
src/helpers/Vector.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "Vector.hpp"
|
||||||
|
|
||||||
|
Vector2D::Vector2D(double xx, double yy) {
|
||||||
|
x = xx;
|
||||||
|
y = yy;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2D::Vector2D() { x = 0; y = 0; }
|
||||||
|
Vector2D::~Vector2D() {}
|
||||||
|
|
||||||
|
double Vector2D::normalize() {
|
||||||
|
// get max abs
|
||||||
|
const auto max = abs(x) > abs(y) ? abs(x) : abs(y);
|
||||||
|
|
||||||
|
x /= max;
|
||||||
|
y /= max;
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
29
src/helpers/Vector.hpp
Normal file
29
src/helpers/Vector.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
class Vector2D {
|
||||||
|
public:
|
||||||
|
Vector2D(double, double);
|
||||||
|
Vector2D();
|
||||||
|
~Vector2D();
|
||||||
|
|
||||||
|
double x = 0;
|
||||||
|
double y = 0;
|
||||||
|
|
||||||
|
// returns the scale
|
||||||
|
double normalize();
|
||||||
|
|
||||||
|
Vector2D operator+(Vector2D a) {
|
||||||
|
return Vector2D(this->x + a.x, this->y + a.y);
|
||||||
|
}
|
||||||
|
Vector2D operator-(Vector2D a) {
|
||||||
|
return Vector2D(this->x - a.x, this->y - a.y);
|
||||||
|
}
|
||||||
|
Vector2D operator*(float a) {
|
||||||
|
return Vector2D(this->x * a, this->y * a);
|
||||||
|
}
|
||||||
|
Vector2D operator/(float a) {
|
||||||
|
return Vector2D(this->x / a, this->y / a);
|
||||||
|
}
|
||||||
|
};
|
32
src/main.cpp
Normal file
32
src/main.cpp
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Hypr Window Manager for X.
|
||||||
|
Started by Vaxry on 2021 / 11 / 17
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "windowManager.hpp"
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
Debug::log(LOG, "Hypr debug log. Built on " + std::string(__DATE__) + " at " + std::string(__TIME__));
|
||||||
|
|
||||||
|
WindowManager::DisplayConnection = xcb_connect(NULL, NULL);
|
||||||
|
if (const auto RET = xcb_connection_has_error(WindowManager::DisplayConnection); RET != 0) {
|
||||||
|
Debug::log(CRIT, "Connection Failed! Return: " + std::to_string(RET));
|
||||||
|
return RET;
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowManager::Screen = xcb_setup_roots_iterator(xcb_get_setup(WindowManager::DisplayConnection)).data;
|
||||||
|
|
||||||
|
WindowManager::setupManager();
|
||||||
|
|
||||||
|
Debug::log(LOG, "Hypr Started!");
|
||||||
|
|
||||||
|
while (WindowManager::handleEvent()) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Hypr reached the end! Exiting...");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
26
src/utilities/Debug.cpp
Normal file
26
src/utilities/Debug.cpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "Debug.hpp"
|
||||||
|
|
||||||
|
void Debug::log(LogLevel level, std::string msg) {
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case LOG:
|
||||||
|
msg = "[LOG] " + msg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WARN:
|
||||||
|
msg = "[WARN] " + msg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERR:
|
||||||
|
msg = "[ERR] " + msg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CRIT:
|
||||||
|
msg = "[CRITICAL] " + msg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf((msg + "\n").c_str());
|
||||||
|
}
|
14
src/utilities/Debug.hpp
Normal file
14
src/utilities/Debug.hpp
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum LogLevel {
|
||||||
|
NONE = -1,
|
||||||
|
LOG = 0,
|
||||||
|
WARN,
|
||||||
|
ERR,
|
||||||
|
CRIT
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Debug {
|
||||||
|
void log(LogLevel, std::string msg);
|
||||||
|
};
|
9
src/utilities/Keybind.hpp
Normal file
9
src/utilities/Keybind.hpp
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include "../defines.hpp"
|
||||||
|
|
||||||
|
class Keybind {
|
||||||
|
EXPOSED_MEMBER(Mod, int, i);
|
||||||
|
EXPOSED_MEMBER(Keysym, xcb_keysym_t,);
|
||||||
|
EXPOSED_MEMBER(Command, std::string, sz);
|
||||||
|
EXPOSED_MEMBER(Dispatcher, void*, p);
|
||||||
|
};
|
||||||
|
|
4
src/window.cpp
Normal file
4
src/window.cpp
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#include "window.hpp"
|
||||||
|
|
||||||
|
CWindow::CWindow() { this->setDirty(true); }
|
||||||
|
CWindow::~CWindow() { }
|
29
src/window.hpp
Normal file
29
src/window.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "defines.hpp"
|
||||||
|
|
||||||
|
class CWindow {
|
||||||
|
public:
|
||||||
|
CWindow();
|
||||||
|
~CWindow();
|
||||||
|
|
||||||
|
void move(Vector2D dest);
|
||||||
|
void moveByDelta(Vector2D delta);
|
||||||
|
|
||||||
|
void resize(Vector2D size);
|
||||||
|
void resize(float percx, float percy);
|
||||||
|
|
||||||
|
std::string getName();
|
||||||
|
|
||||||
|
// Tells the window manager to reload the window's params
|
||||||
|
EXPOSED_MEMBER(Dirty, bool, b);
|
||||||
|
|
||||||
|
EXPOSED_MEMBER(Size, Vector2D, vec);
|
||||||
|
EXPOSED_MEMBER(Position, Vector2D, vec);
|
||||||
|
EXPOSED_MEMBER(IsFloating, bool, b);
|
||||||
|
EXPOSED_MEMBER(Drawable, xcb_drawable_t, i);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
226
src/windowManager.cpp
Normal file
226
src/windowManager.cpp
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
#include "windowManager.hpp"
|
||||||
|
#include "./events/events.hpp"
|
||||||
|
|
||||||
|
void WindowManager::setupManager() {
|
||||||
|
WindowManager::Values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
|
||||||
|
xcb_change_window_attributes_checked(WindowManager::DisplayConnection, WindowManager::Screen->root,
|
||||||
|
XCB_CW_EVENT_MASK, WindowManager::Values);
|
||||||
|
xcb_ungrab_key(WindowManager::DisplayConnection, XCB_GRAB_ANY, WindowManager::Screen->root, XCB_MOD_MASK_ANY);
|
||||||
|
/*int key_table_size = sizeof(keys) / sizeof(*keys);
|
||||||
|
for (int i = 0; i < key_table_size; ++i) {
|
||||||
|
xcb_keycode_t *keycode = xcb_get_keycodes(keys[i].keysym);
|
||||||
|
if (keycode != NULL) {
|
||||||
|
xcb_grab_key(WindowManager::DisplayConnection, 1, WindowManager::Screen->root, keys[i].mod, *keycode,
|
||||||
|
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xcb_flush(WindowManager::DisplayConnection);
|
||||||
|
xcb_grab_button(WindowManager::DisplayConnection, 0, WindowManager::Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC,
|
||||||
|
XCB_GRAB_MODE_ASYNC, WindowManager::Screen->root, XCB_NONE, 1, MOD1);
|
||||||
|
xcb_grab_button(WindowManager::DisplayConnection, 0, WindowManager::Screen->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC,
|
||||||
|
XCB_GRAB_MODE_ASYNC, WindowManager::Screen->root, XCB_NONE, 3, MOD1);*/
|
||||||
|
xcb_flush(WindowManager::DisplayConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowManager::handleEvent() {
|
||||||
|
if (xcb_connection_has_error(WindowManager::DisplayConnection))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
xcb_generic_event_t* ev = xcb_wait_for_event(WindowManager::DisplayConnection);
|
||||||
|
if (ev != NULL) {
|
||||||
|
switch (ev->response_type & ~0x80) {
|
||||||
|
case XCB_ENTER_NOTIFY:
|
||||||
|
Events::eventEnter(ev);
|
||||||
|
Debug::log(LOG, "Event dispatched ENTER");
|
||||||
|
break;
|
||||||
|
case XCB_DESTROY_NOTIFY:
|
||||||
|
Events::eventDestroy(ev);
|
||||||
|
Debug::log(LOG, "Event dispatched DESTROY");
|
||||||
|
break;
|
||||||
|
case XCB_MAP_REQUEST:
|
||||||
|
Events::eventMapWindow(ev);
|
||||||
|
Debug::log(LOG, "Event dispatched MAP");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Debug::log(WARN, "Unknown event: " + std::to_string(ev->response_type & ~0x80));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh and apply the parameters of all dirty windows.
|
||||||
|
WindowManager::refreshDirtyWindows();
|
||||||
|
|
||||||
|
xcb_flush(WindowManager::DisplayConnection);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::refreshDirtyWindows() {
|
||||||
|
for(auto& window : windows) {
|
||||||
|
if (window.getDirty()) {
|
||||||
|
Values[0] = (int)window.getSize().x;
|
||||||
|
Values[1] = (int)window.getSize().y;
|
||||||
|
xcb_configure_window(WindowManager::DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, Values);
|
||||||
|
|
||||||
|
Values[0] = (int)window.getPosition().x;
|
||||||
|
Values[1] = (int)window.getPosition().y;
|
||||||
|
xcb_configure_window(WindowManager::DisplayConnection, window.getDrawable(), XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, Values);
|
||||||
|
|
||||||
|
window.setDirty(false);
|
||||||
|
|
||||||
|
Debug::log(LOG, "Refreshed dirty window.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::setFocusedWindow(xcb_drawable_t window) {
|
||||||
|
if (window && window != WindowManager::Screen->root) {
|
||||||
|
xcb_set_input_focus(WindowManager::DisplayConnection, XCB_INPUT_FOCUS_POINTER_ROOT, window, XCB_CURRENT_TIME);
|
||||||
|
WindowManager::LastWindow = window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CWindow* WindowManager::getWindowFromDrawable(xcb_drawable_t window) {
|
||||||
|
for(auto& w : WindowManager::windows) {
|
||||||
|
if (w.getDrawable() == window) {
|
||||||
|
return &w;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug::log(LOG, "Not " + std::to_string(w.getDrawable()));
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::addWindowToVectorSafe(CWindow window) {
|
||||||
|
for (auto& w : WindowManager::windows) {
|
||||||
|
if (w.getDrawable() == window.getDrawable())
|
||||||
|
return; // Do not add if already present.
|
||||||
|
}
|
||||||
|
WindowManager::windows.push_back(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::removeWindowFromVectorSafe(xcb_drawable_t window) {
|
||||||
|
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<CWindow> temp = WindowManager::windows;
|
||||||
|
|
||||||
|
WindowManager::windows.clear();
|
||||||
|
|
||||||
|
for(auto p : temp) {
|
||||||
|
if (p.getDrawable() != window) {
|
||||||
|
WindowManager::windows.push_back(p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Debug::log(LOG, "Is, removing: " + std::to_string(p.getDrawable()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void calculateNewTileSetOldTile(CWindow* pWindow) {
|
||||||
|
const auto PLASTWINDOW = WindowManager::getWindowFromDrawable(WindowManager::LastWindow);
|
||||||
|
if (PLASTWINDOW) {
|
||||||
|
const auto PLASTSIZE = PLASTWINDOW->getSize();
|
||||||
|
const auto PLASTPOS = PLASTWINDOW->getPosition();
|
||||||
|
|
||||||
|
if (PLASTSIZE.x > PLASTSIZE.y) {
|
||||||
|
PLASTWINDOW->setSize(Vector2D(PLASTSIZE.x / 2.f, PLASTSIZE.y));
|
||||||
|
pWindow->setSize(Vector2D(PLASTSIZE.x / 2.f, PLASTSIZE.y));
|
||||||
|
pWindow->setPosition(Vector2D(PLASTPOS.x + PLASTSIZE.x / 2.f, PLASTPOS.y));
|
||||||
|
} else {
|
||||||
|
PLASTWINDOW->setSize(Vector2D(PLASTSIZE.x, PLASTSIZE.y / 2.f));
|
||||||
|
pWindow->setSize(Vector2D(PLASTSIZE.x, PLASTSIZE.y / 2.f));
|
||||||
|
pWindow->setPosition(Vector2D(PLASTPOS.x, PLASTPOS.y + PLASTSIZE.y / 2.f));
|
||||||
|
}
|
||||||
|
|
||||||
|
PLASTWINDOW->setDirty(true);
|
||||||
|
} else {
|
||||||
|
// Open a fullscreen window
|
||||||
|
pWindow->setSize(Vector2D(WindowManager::Screen->width_in_pixels, WindowManager::Screen->height_in_pixels));
|
||||||
|
pWindow->setPosition(Vector2D(0, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::calculateNewWindowParams(CWindow* pWindow) {
|
||||||
|
// And set old one's if needed.
|
||||||
|
if (!pWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!pWindow->getIsFloating()) {
|
||||||
|
calculateNewTileSetOldTile(pWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
pWindow->setDirty(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNeighbor(CWindow* a, CWindow* b) {
|
||||||
|
const auto POSA = a->getPosition();
|
||||||
|
const auto POSB = b->getPosition();
|
||||||
|
const auto SIZEA = a->getSize();
|
||||||
|
const auto SIZEB = a->getSize();
|
||||||
|
|
||||||
|
if (POSA.x != 0) {
|
||||||
|
if (STICKS(POSA.x, (POSB.x + SIZEB.x))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (POSA.y != 0) {
|
||||||
|
if (STICKS(POSA.y, (POSB.y + SIZEB.y))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (POSB.x != 0) {
|
||||||
|
if (STICKS(POSB.x, (POSA.x + SIZEA.x))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (POSB.y != 0) {
|
||||||
|
if (STICKS(POSB.y, (POSA.y + SIZEA.y))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void eatWindow(CWindow* a, CWindow* toEat) {
|
||||||
|
|
||||||
|
// Pos is min of both.
|
||||||
|
a->setPosition(Vector2D(std::min(a->getPosition().x, toEat->getPosition().x), std::min(a->getPosition().y, toEat->getPosition().y)));
|
||||||
|
|
||||||
|
// Size is pos + size max - pos
|
||||||
|
const auto OPPCORNERA = a->getPosition() + a->getSize();
|
||||||
|
const auto OPPCORNERB = toEat->getPosition() + toEat->getSize();
|
||||||
|
|
||||||
|
a->setSize(Vector2D(std::max(OPPCORNERA.x, OPPCORNERB.x), std::max(OPPCORNERA.y, OPPCORNERB.y)) - a->getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowManager::fixWindowOnClose(CWindow* pClosedWindow) {
|
||||||
|
if (!pClosedWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// get the first neighboring window
|
||||||
|
CWindow* neighbor = nullptr;
|
||||||
|
for(auto& w : WindowManager::windows) {
|
||||||
|
if (w.getDrawable() == pClosedWindow->getDrawable())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (isNeighbor(&w, pClosedWindow)) {
|
||||||
|
neighbor = &w;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!neighbor)
|
||||||
|
return; // No neighbor. Don't update, easy.
|
||||||
|
|
||||||
|
|
||||||
|
// update neighbor to "eat" closed.
|
||||||
|
eatWindow(neighbor, pClosedWindow);
|
||||||
|
|
||||||
|
neighbor->setDirty(true);
|
||||||
|
}
|
29
src/windowManager.hpp
Normal file
29
src/windowManager.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "defines.hpp"
|
||||||
|
#include "window.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace WindowManager {
|
||||||
|
inline xcb_connection_t* DisplayConnection;
|
||||||
|
inline xcb_screen_t* Screen;
|
||||||
|
inline xcb_drawable_t Drawable;
|
||||||
|
inline uint32_t Values[3];
|
||||||
|
|
||||||
|
inline std::vector<CWindow> windows; // windows never left. It has always been hiding amongst us.
|
||||||
|
inline xcb_drawable_t LastWindow = -1;
|
||||||
|
|
||||||
|
CWindow* getWindowFromDrawable(xcb_drawable_t);
|
||||||
|
void addWindowToVectorSafe(CWindow);
|
||||||
|
void removeWindowFromVectorSafe(xcb_drawable_t);
|
||||||
|
|
||||||
|
void setupManager();
|
||||||
|
bool handleEvent();
|
||||||
|
void refreshDirtyWindows();
|
||||||
|
|
||||||
|
void setFocusedWindow(xcb_drawable_t);
|
||||||
|
|
||||||
|
void calculateNewWindowParams(CWindow*);
|
||||||
|
void fixWindowOnClose(CWindow*);
|
||||||
|
};
|
Loading…
Reference in a new issue