Fix float windows

- Add parameter general:float_min_crop for support minimal size window
   cropping for windows that cannot transition to float.
 - Add parameter general:float_center_screen to control spawn new float windows.
   1 - New float windows spawn in center screen.
   0 - Сonsider the trimming at the top and bottom to calculate the center of the screen.
   For example, consider the size of the waybar.
 - Fix float windows
 - Fix togglefloat
 - Fix windows that start float and then go into a normal window, aka
   program launchers. Example: Blizzard battle.net client.
   The bug render full-screen programs partially behind the screen.
   Now the xwayland games launch normally.
 - Code cleanup and refactoring.
 - Replaced vec() with goalv() in logic other than animation,
   it seemed to me more correct because goalv() is used in many places.
   Not sure if this is correct.
This commit is contained in:
Grigory Vasilyev 2023-11-27 11:05:37 +03:00
parent 6e8b9ef7d8
commit dd3b6e1bf0
No known key found for this signature in database
GPG key ID: C4C1F715B2B66B95
5 changed files with 83 additions and 29 deletions

View file

@ -214,6 +214,8 @@ class CWindow {
// for restoring floating statuses // for restoring floating statuses
Vector2D m_vLastFloatingSize; Vector2D m_vLastFloatingSize;
Vector2D m_vLastFloatingPosition; Vector2D m_vLastFloatingPosition;
Vector2D m_vLastFloatingCropSize;
bool m_vLastFloatingCenterScreen;
// this is used for pseudotiling // this is used for pseudotiling
bool m_bIsPseudotiled = false; bool m_bIsPseudotiled = false;

View file

@ -94,6 +94,8 @@ void CConfigManager::setDefaultVars() {
configValues["general:resize_on_border"].intValue = 0; configValues["general:resize_on_border"].intValue = 0;
configValues["general:extend_border_grab_area"].intValue = 15; configValues["general:extend_border_grab_area"].intValue = 15;
configValues["general:hover_icon_on_border"].intValue = 1; configValues["general:hover_icon_on_border"].intValue = 1;
configValues["general:float_min_crop"].vecValue = Vector2D(0.25, 0.25);
configValues["general:float_center_screen"].intValue = 0;
configValues["general:layout"].strValue = "dwindle"; configValues["general:layout"].strValue = "dwindle";
configValues["general:allow_tearing"].intValue = 0; configValues["general:allow_tearing"].intValue = 0;

View file

@ -1043,13 +1043,21 @@ void Events::listener_configureX11(void* owner, void* data) {
PWINDOW->m_vRealPosition.setValueAndWarp(LOGICALPOS); PWINDOW->m_vRealPosition.setValueAndWarp(LOGICALPOS);
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height)); PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(E->width, E->height));
auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (!PMONITOR) {
PMONITOR = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.0);
PWINDOW->m_iMonitorID = PMONITOR->ID;
}
static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue; static auto* const PXWLFORCESCALEZERO = &g_pConfigManager->getConfigValuePtr("xwayland:force_zero_scaling")->intValue;
if (*PXWLFORCESCALEZERO) { if (*PXWLFORCESCALEZERO) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) { PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale);
const Vector2D DELTA = PWINDOW->m_vRealSize.goalv() - PWINDOW->m_vRealSize.goalv() / PMONITOR->scale; static auto* const FLOATCENTERSCREEN = &g_pConfigManager->getConfigValuePtr("general:float_center_screen")->intValue;
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale); PWINDOW->m_vLastFloatingCenterScreen = *FLOATCENTERSCREEN;
PWINDOW->m_vRealPosition.setValueAndWarp(PWINDOW->m_vRealPosition.goalv() + DELTA / 2.0); if (*FLOATCENTERSCREEN)
} PWINDOW->m_vRealPosition.setValueAndWarp(PMONITOR->vecPosition + (PMONITOR->vecSize - PWINDOW->m_vRealSize.goalv()) / 2.0);
else
PWINDOW->m_vRealPosition.setValueAndWarp(PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft +
(PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight - PWINDOW->m_vRealSize.goalv()) / 2.0);
} }
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec(); PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.vec();
@ -1057,7 +1065,7 @@ void Events::listener_configureX11(void* owner, void* data) {
wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height); wlr_xwayland_surface_configure(PWINDOW->m_uSurface.xwayland, E->x, E->y, E->width, E->height);
PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.vec() + PWINDOW->m_vRealSize.vec() / 2.f)->activeWorkspace; PWINDOW->m_iWorkspaceID = PMONITOR->activeWorkspace;
g_pCompositor->changeWindowZOrder(PWINDOW, true); g_pCompositor->changeWindowZOrder(PWINDOW, true);
@ -1108,18 +1116,28 @@ void Events::listener_unmanagedSetGeometry(void* owner, void* data) {
if (abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2) if (abs(std::floor(SIZ.x) - PWINDOW->m_uSurface.xwayland->width) > 2 || abs(std::floor(SIZ.y) - PWINDOW->m_uSurface.xwayland->height) > 2)
PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height)); PWINDOW->m_vRealSize.setValueAndWarp(Vector2D(PWINDOW->m_uSurface.xwayland->width, PWINDOW->m_uSurface.xwayland->height));
auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID);
if (!PMONITOR) {
PMONITOR = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.goalv() + PWINDOW->m_vRealSize.goalv() / 2.0);
PWINDOW->m_iMonitorID = PMONITOR->ID;
}
if (*PXWLFORCESCALEZERO) { if (*PXWLFORCESCALEZERO) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(PWINDOW->m_iMonitorID); PMONITOR) { PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale);
const Vector2D DELTA = PWINDOW->m_vRealSize.goalv() - PWINDOW->m_vRealSize.goalv() / PMONITOR->scale; static auto* const FLOATCENTERSCREEN = &g_pConfigManager->getConfigValuePtr("general:float_center_screen")->intValue;
PWINDOW->m_vRealSize.setValueAndWarp(PWINDOW->m_vRealSize.goalv() / PMONITOR->scale); PWINDOW->m_vLastFloatingCenterScreen = *FLOATCENTERSCREEN;
PWINDOW->m_vRealPosition.setValueAndWarp(PWINDOW->m_vRealPosition.goalv() + DELTA / 2.0); if (*FLOATCENTERSCREEN)
} PWINDOW->m_vRealPosition.setValueAndWarp(PMONITOR->vecPosition + (PMONITOR->vecSize - PWINDOW->m_vRealSize.goalv()) / 2.0);
else
PWINDOW->m_vRealPosition.setValueAndWarp(PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft +
(PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight - PWINDOW->m_vRealSize.goalv()) /
2.0);
} }
PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goalv(); PWINDOW->m_vPosition = PWINDOW->m_vRealPosition.goalv();
PWINDOW->m_vSize = PWINDOW->m_vRealSize.goalv(); PWINDOW->m_vSize = PWINDOW->m_vRealSize.goalv();
PWINDOW->m_iWorkspaceID = g_pCompositor->getMonitorFromVector(PWINDOW->m_vRealPosition.vec() + PWINDOW->m_vRealSize.vec() / 2.f)->activeWorkspace; PWINDOW->m_iWorkspaceID = PMONITOR->activeWorkspace;
g_pCompositor->changeWindowZOrder(PWINDOW, true); g_pCompositor->changeWindowZOrder(PWINDOW, true);
PWINDOW->updateWindowDecos(); PWINDOW->updateWindowDecos();

View file

@ -455,9 +455,10 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
// if the window is pseudo, update its size // if the window is pseudo, update its size
if (!pWindow->m_bDraggingTiled) if (!pWindow->m_bDraggingTiled)
pWindow->m_vPseudoSize = pWindow->m_vRealSize.goalv(); pWindow->m_vPseudoSize = PSAVEDSIZE;
pWindow->m_vLastFloatingSize = PSAVEDSIZE; pWindow->m_vLastFloatingPosition = PSAVEDPOS;
pWindow->m_vLastFloatingSize = PSAVEDSIZE;
// move to narnia because we don't wanna find our own node. onWindowCreatedTiling should apply the coords back. // move to narnia because we don't wanna find our own node. onWindowCreatedTiling should apply the coords back.
pWindow->m_vPosition = Vector2D(-999999, -999999); pWindow->m_vPosition = Vector2D(-999999, -999999);
@ -477,18 +478,50 @@ void IHyprLayout::changeWindowFloatingMode(CWindow* pWindow) {
g_pCompositor->changeWindowZOrder(pWindow, true); g_pCompositor->changeWindowZOrder(pWindow, true);
if (DELTALESSTHAN(pWindow->m_vRealSize.vec().x, pWindow->m_vLastFloatingSize.x, 10) && DELTALESSTHAN(pWindow->m_vRealSize.vec().y, pWindow->m_vLastFloatingSize.y, 10)) { auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID);
pWindow->m_vRealPosition = pWindow->m_vRealPosition.goalv() + (pWindow->m_vRealSize.goalv() - pWindow->m_vLastFloatingSize) / 2.f + Vector2D{10, 10}; if (!PMONITOR) {
pWindow->m_vRealSize = pWindow->m_vLastFloatingSize - Vector2D{20, 20}; PMONITOR = g_pCompositor->getMonitorFromVector(pWindow->m_vRealPosition.goalv() + pWindow->m_vRealSize.goalv() / 2.0);
pWindow->m_iMonitorID = PMONITOR->ID;
}
const auto PSAVEDSIZE = pWindow->m_vRealSize.goalv();
static auto* const FLOATMINCROP = &g_pConfigManager->getConfigValuePtr("general:float_min_crop")->vecValue;
Vector2D cropSize = {0, 0};
if (FLOATMINCROP->x > 0 && FLOATMINCROP->x < 1.0)
cropSize.x = PSAVEDSIZE.x * FLOATMINCROP->x;
else
cropSize.x = FLOATMINCROP->x;
if (FLOATMINCROP->y > 0 && FLOATMINCROP->y < 1.0)
cropSize.y = PSAVEDSIZE.y * FLOATMINCROP->y;
else
cropSize.y = FLOATMINCROP->y;
if ((pWindow->m_vLastFloatingCropSize.x > 0 && pWindow->m_vLastFloatingCropSize.y > 0 && pWindow->m_vLastFloatingCropSize.x != cropSize.x &&
pWindow->m_vLastFloatingCropSize.y != cropSize.y) ||
(DELTALESSTHAN(PSAVEDSIZE.x, pWindow->m_vLastFloatingSize.x, cropSize.x) && DELTALESSTHAN(PSAVEDSIZE.y, pWindow->m_vLastFloatingSize.y, cropSize.y))) {
pWindow->m_vLastFloatingSize = PSAVEDSIZE - cropSize;
pWindow->m_vLastFloatingPosition = {0, 0};
pWindow->m_vLastFloatingCropSize = cropSize;
}
static auto* const FLOATCENTERSCREEN = &g_pConfigManager->getConfigValuePtr("general:float_center_screen")->intValue;
if (pWindow->m_vLastFloatingPosition.x <= 0 || pWindow->m_vLastFloatingPosition.y <= 0) {
if (*FLOATCENTERSCREEN) {
pWindow->m_vLastFloatingPosition = PMONITOR->vecPosition + (PMONITOR->vecSize - pWindow->m_vLastFloatingSize) / 2.0;
} else {
pWindow->m_vLastFloatingPosition = PMONITOR->vecPosition + PMONITOR->vecReservedTopLeft +
(PMONITOR->vecSize - PMONITOR->vecReservedTopLeft - PMONITOR->vecReservedBottomRight - pWindow->m_vLastFloatingSize) / 2.0;
}
pWindow->m_vLastFloatingCenterScreen = *FLOATCENTERSCREEN;
} }
pWindow->m_vRealPosition = pWindow->m_vRealPosition.goalv() + (pWindow->m_vRealSize.goalv() - pWindow->m_vLastFloatingSize) / 2.f;
pWindow->m_vRealSize = pWindow->m_vLastFloatingSize; pWindow->m_vRealSize = pWindow->m_vLastFloatingSize;
pWindow->m_vRealPosition = pWindow->m_vLastFloatingPosition;
pWindow->m_vSize = pWindow->m_vRealSize.goalv(); pWindow->m_vSize = pWindow->m_vRealSize.goalv();
pWindow->m_vPosition = pWindow->m_vRealPosition.goalv(); pWindow->m_vPosition = pWindow->m_vRealPosition.goalv();
g_pHyprRenderer->damageMonitor(g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID)); g_pHyprRenderer->damageMonitor(PMONITOR);
pWindow->updateSpecialRenderData(); pWindow->updateSpecialRenderData();

View file

@ -172,16 +172,13 @@ void CHyprXWaylandManager::setWindowSize(CWindow* pWindow, Vector2D size, bool f
pWindow->m_fX11SurfaceScaledBy = 1.f; pWindow->m_fX11SurfaceScaledBy = 1.f;
if (*PXWLFORCESCALEZERO && pWindow->m_bIsX11) { if (pWindow->m_bIsX11) {
if (const auto PMONITOR = g_pCompositor->getMonitorFromID(pWindow->m_iMonitorID); PMONITOR) { if (*PXWLFORCESCALEZERO) {
size = size * PMONITOR->scale; size = size * PMONITOR->scale;
pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale; pWindow->m_fX11SurfaceScaledBy = PMONITOR->scale;
} }
}
if (pWindow->m_bIsX11)
wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, windowPos.x, windowPos.y, size.x, size.y); wlr_xwayland_surface_configure(pWindow->m_uSurface.xwayland, windowPos.x, windowPos.y, size.x, size.y);
else } else
pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y), size.floor())); pWindow->m_vPendingSizeAcks.push_back(std::make_pair<>(wlr_xdg_toplevel_set_size(pWindow->m_uSurface.xdg->toplevel, size.x, size.y), size.floor()));
} }
@ -242,13 +239,15 @@ bool CHyprXWaylandManager::shouldBeFloated(CWindow* pWindow) {
return true; // override_redirect return true; // override_redirect
const auto SIZEHINTS = pWindow->m_uSurface.xwayland->size_hints; const auto SIZEHINTS = pWindow->m_uSurface.xwayland->size_hints;
if (SIZEHINTS && (pWindow->m_uSurface.xwayland->parent || ((SIZEHINTS->min_width == SIZEHINTS->max_width) && (SIZEHINTS->min_height == SIZEHINTS->max_height)))) if (SIZEHINTS &&
(pWindow->m_uSurface.xwayland->parent ||
(SIZEHINTS->min_width > 0 && SIZEHINTS->min_height > 0 && SIZEHINTS->min_width == SIZEHINTS->max_width && SIZEHINTS->min_height == SIZEHINTS->max_height)))
return true; return true;
} else { } else {
const auto PSTATE = &pWindow->m_uSurface.xdg->toplevel->current; const auto PSTATE = &pWindow->m_uSurface.xdg->toplevel->current;
if (PSTATE &&
if ((PSTATE->min_width != 0 && PSTATE->min_height != 0 && (PSTATE->min_width == PSTATE->max_width || PSTATE->min_height == PSTATE->max_height)) || (pWindow->m_uSurface.xdg->toplevel->parent ||
pWindow->m_uSurface.xdg->toplevel->parent) (PSTATE->min_width > 0 && PSTATE->min_height > 0 && PSTATE->min_width == PSTATE->max_width && PSTATE->min_height == PSTATE->max_height)))
return true; return true;
} }