diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 177636f..470101f 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@v2 - name: getpkgs - run: sudo apt install xcb cmake gcc libgtk-3-dev ninja-build libgtkmm-3.0-dev libxcb-randr0 libxcb-randr0-dev libxcb-util-dev libxcb-util0-dev libxcb-util1 libxcb-ewmh-dev libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4-dev libxcb-keysyms1-dev libxcb-cursor-dev + run: sudo apt install xcb cmake gcc libgtk-3-dev ninja-build libgtkmm-3.0-dev libxcb-randr0 libxcb-randr0-dev libxcb-util-dev libxcb-util0-dev libxcb-util1 libxcb-ewmh-dev libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4-dev libxcb-keysyms1-dev libxcb-cursor-dev libxcb-shape0-dev - name: configure run: make clear - name: make diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c0c349c..975ff7f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -63,7 +63,7 @@ jobs: # uses a compiled language - run: | - sudo apt install xcb cmake gcc libgtk-3-dev ninja-build libgtkmm-3.0-dev libxcb-randr0 libxcb-randr0-dev libxcb-util-dev libxcb-util0-dev libxcb-util1 libxcb-ewmh-dev libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4-dev libxcb-keysyms1-dev libxcb-cursor-dev + sudo apt install xcb cmake gcc libgtk-3-dev ninja-build libgtkmm-3.0-dev libxcb-randr0 libxcb-randr0-dev libxcb-util-dev libxcb-util0-dev libxcb-util1 libxcb-ewmh-dev libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4-dev libxcb-keysyms1-dev libxcb-cursor-dev libxcb-shape0-dev make clear make release diff --git a/CMakeLists.txt b/CMakeLists.txt index 5310007..d9b7817 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,5 +31,6 @@ target_link_libraries(Hypr xcb-randr xcb-xinerama xcb-cursor + xcb-shape ${CMAKE_THREAD_LIBS_INIT} ) \ No newline at end of file diff --git a/README.md b/README.md index be0fcca..b97f35c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Hypr is a Linux tiling window manager for Xorg. It's written in XCB with modern ## Roadmap v2 (not in order) - [x] Upgrade the status bar rendering to Cairo - [x] Better status bar configability ~ WIP -- [ ] Rounded corners +- [x] Rounded corners ~ meh - [x] Replace default X11 cursor with the pointer - [x] Fix ghost windows once and for all - [ ] Fix windows minimizing themselves to tray not being able to come back without pkill diff --git a/example/hypr.conf b/example/hypr.conf index 77588a1..77cd364 100644 --- a/example/hypr.conf +++ b/example/hypr.conf @@ -6,6 +6,7 @@ gaps_in=5 border_size=1 gaps_out=20 +rounding=0 max_fps=60 # max fps for updates of config & animations # Bar config diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 02f7487..090189f 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -13,6 +13,7 @@ void ConfigManager::init() { configValues["border_size"].intValue = 1; configValues["gaps_in"].intValue = 5; configValues["gaps_out"].intValue = 20; + configValues["rounding"].intValue = 5; configValues["max_fps"].intValue = 60; diff --git a/src/defines.hpp b/src/defines.hpp index 18c00e0..1606794 100644 --- a/src/defines.hpp +++ b/src/defines.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/src/windowManager.cpp b/src/windowManager.cpp index a6f06ad..45a58bb 100644 --- a/src/windowManager.cpp +++ b/src/windowManager.cpp @@ -373,6 +373,9 @@ void CWindowManager::refreshDirtyWindows() { xcb_change_window_attributes(DisplayConnection, window.getDrawable(), XCB_CW_BORDER_PIXEL, Values); } + // Apply rounded corners, does all the checks inside + applyRoundedCornersToWindow(&window); + Debug::log(LOG, "Refreshed dirty window, with an ID of " + std::to_string(window.getDrawable())); } } @@ -530,6 +533,62 @@ void CWindowManager::removeWindowFromVectorSafe(int64_t window) { } } +void CWindowManager::applyRoundedCornersToWindow(CWindow* pWindow) { + if (!pWindow) + return; + + const auto ROUNDING = ConfigManager::getInt("rounding"); + + if (!ROUNDING) + return; + + const auto SHAPEQUERY = xcb_get_extension_data(DisplayConnection, &xcb_shape_id); + + if (!SHAPEQUERY || !SHAPEQUERY->present || pWindow->getNoInterventions() || pWindow->getFullscreen()) + return; + + + const xcb_pixmap_t PIXMAPID = xcb_generate_id(DisplayConnection); + xcb_create_pixmap(DisplayConnection, 1, PIXMAPID, pWindow->getDrawable(), pWindow->getRealSize().x, pWindow->getRealSize().y); + + const xcb_gcontext_t BLACKPIXEL = xcb_generate_id(DisplayConnection); + const xcb_gcontext_t WHITEPIXEL = xcb_generate_id(DisplayConnection); + + Values[0] = 0; + Values[1] = 0; + xcb_create_gc(DisplayConnection, BLACKPIXEL, PIXMAPID, XCB_GC_FOREGROUND, Values); + Values[0] = 1; + xcb_create_gc(DisplayConnection, WHITEPIXEL, PIXMAPID, XCB_GC_FOREGROUND, Values); + + const auto R = (uint16_t)(ROUNDING); + const auto D = (uint16_t)(2 * ROUNDING); + const auto H = (uint16_t)(pWindow->getRealSize().y); + const auto W = (uint16_t)(pWindow->getRealSize().x); + + const xcb_arc_t ARCS[] = { + {0, 0, D, D, 0, 360 << 6}, + {0, H - D - 1, D, D, 0, 360 << 6}, + {W - D - 1, 0, D, D, 0, 360 << 6}, + {W - D - 1, H - D - 1, D, D, 0, 360 << 6} + }; + + const xcb_rectangle_t RECTANGLES[] = { + {R, 0, W - D, H}, + {0, R, W, H - D} + }; + + const xcb_rectangle_t WINDOWRECT = {0,0,W,H}; + + xcb_poly_fill_rectangle(DisplayConnection, PIXMAPID, BLACKPIXEL, 1, &WINDOWRECT); + xcb_poly_fill_rectangle(DisplayConnection, PIXMAPID, WHITEPIXEL, 2, RECTANGLES); + xcb_poly_fill_arc(DisplayConnection, PIXMAPID, WHITEPIXEL, 4, ARCS); + + xcb_shape_mask(DisplayConnection, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, pWindow->getDrawable(), 0, 0, PIXMAPID); + xcb_shape_mask(DisplayConnection, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_CLIP, pWindow->getDrawable(), 0, 0, PIXMAPID); + + xcb_free_pixmap(DisplayConnection, PIXMAPID); +} + void CWindowManager::setEffectiveSizePosUsingConfig(CWindow* pWindow) { if (!pWindow || pWindow->getIsFloating()) diff --git a/src/windowManager.hpp b/src/windowManager.hpp index ddaf231..db8e393 100644 --- a/src/windowManager.hpp +++ b/src/windowManager.hpp @@ -116,6 +116,7 @@ public: void cleanupUnusedWorkspaces(); xcb_visualtype_t* setupColors(); void updateRootCursor(); + void applyRoundedCornersToWindow(CWindow* pWindow); }; inline std::unique_ptr g_pWindowManager = std::make_unique();