Changeset View
Changeset View
Standalone View
Standalone View
x11client.cpp
Show First 20 Lines • Show All 647 Lines • ▼ Show 20 Line(s) | 591 | #endif | |||
---|---|---|---|---|---|
648 | // Maximization for oversized windows must happen NOW. | 648 | // Maximization for oversized windows must happen NOW. | ||
649 | // If we effectively pass keepInArea(), the window will resizeWithChecks() - i.e. constrained | 649 | // If we effectively pass keepInArea(), the window will resizeWithChecks() - i.e. constrained | ||
650 | // to the combo of all screen MINUS all struts on the edges | 650 | // to the combo of all screen MINUS all struts on the edges | ||
651 | // If only one screen struts, this will affect screens as a side-effect, the window is artificailly shrinked | 651 | // If only one screen struts, this will affect screens as a side-effect, the window is artificailly shrinked | ||
652 | // below the screen size and as result no more maximized what breaks KMainWindow's stupid width+1, height+1 hack | 652 | // below the screen size and as result no more maximized what breaks KMainWindow's stupid width+1, height+1 hack | ||
653 | // TODO: get KMainWindow a correct state storage what will allow to store the restore size as well. | 653 | // TODO: get KMainWindow a correct state storage what will allow to store the restore size as well. | ||
654 | 654 | | |||
655 | if (!session) { // has a better handling of this | 655 | if (!session) { // has a better handling of this | ||
656 | geom_restore = frameGeometry(); // Remember restore geometry | 656 | setGeometryRestore(frameGeometry()); // Remember restore geometry | ||
657 | if (isMaximizable() && (width() >= area.width() || height() >= area.height())) { | 657 | if (isMaximizable() && (width() >= area.width() || height() >= area.height())) { | ||
658 | // Window is too large for the screen, maximize in the | 658 | // Window is too large for the screen, maximize in the | ||
659 | // directions necessary | 659 | // directions necessary | ||
660 | const QSize ss = workspace()->clientArea(ScreenArea, area.center(), desktop()).size(); | 660 | const QSize ss = workspace()->clientArea(ScreenArea, area.center(), desktop()).size(); | ||
661 | const QRect fsa = workspace()->clientArea(FullArea, geom.center(), desktop()); | 661 | const QRect fsa = workspace()->clientArea(FullArea, geom.center(), desktop()); | ||
662 | const QSize cs = clientSize(); | 662 | const QSize cs = clientSize(); | ||
663 | int pseudo_max = ((info->state() & NET::MaxVert) ? MaximizeVertical : 0) | | 663 | int pseudo_max = ((info->state() & NET::MaxVert) ? MaximizeVertical : 0) | | ||
664 | ((info->state() & NET::MaxHoriz) ? MaximizeHorizontal : 0); | 664 | ((info->state() & NET::MaxHoriz) ? MaximizeHorizontal : 0); | ||
Show All 19 Lines | 683 | if (height() < fsa.height() && (cs.height() > ss.height()+1)) { | |||
684 | pseudo_max &= ~MaximizeVertical; | 684 | pseudo_max &= ~MaximizeVertical; | ||
685 | keepInFsArea = true; | 685 | keepInFsArea = true; | ||
686 | } | 686 | } | ||
687 | 687 | | |||
688 | if (pseudo_max != MaximizeRestore) { | 688 | if (pseudo_max != MaximizeRestore) { | ||
689 | maximize((MaximizeMode)pseudo_max); | 689 | maximize((MaximizeMode)pseudo_max); | ||
690 | // from now on, care about maxmode, since the maximization call will override mode for fix aspects | 690 | // from now on, care about maxmode, since the maximization call will override mode for fix aspects | ||
691 | dontKeepInArea |= (max_mode == MaximizeFull); | 691 | dontKeepInArea |= (max_mode == MaximizeFull); | ||
692 | geom_restore = QRect(); // Use placement when unmaximizing ... | 692 | QRect savedGeometry; // Use placement when unmaximizing ... | ||
693 | if (!(max_mode & MaximizeVertical)) { | 693 | if (!(max_mode & MaximizeVertical)) { | ||
694 | geom_restore.setY(y()); // ...but only for horizontal direction | 694 | savedGeometry.setY(y()); // ...but only for horizontal direction | ||
695 | geom_restore.setHeight(height()); | 695 | savedGeometry.setHeight(height()); | ||
696 | } | 696 | } | ||
697 | if (!(max_mode & MaximizeHorizontal)) { | 697 | if (!(max_mode & MaximizeHorizontal)) { | ||
698 | geom_restore.setX(x()); // ...but only for vertical direction | 698 | savedGeometry.setX(x()); // ...but only for vertical direction | ||
699 | geom_restore.setWidth(width()); | 699 | savedGeometry.setWidth(width()); | ||
700 | } | 700 | } | ||
701 | setGeometryRestore(savedGeometry); | ||||
701 | } | 702 | } | ||
702 | if (keepInFsArea) | 703 | if (keepInFsArea) | ||
703 | keepInArea(fsa, partial_keep_in_area); | 704 | keepInArea(fsa, partial_keep_in_area); | ||
704 | } | 705 | } | ||
705 | } | 706 | } | ||
706 | 707 | | |||
707 | if ((!isSpecialWindow() || isToolbar()) && isMovable() && !dontKeepInArea) | 708 | if ((!isSpecialWindow() || isToolbar()) && isMovable() && !dontKeepInArea) | ||
708 | keepInArea(area, partial_keep_in_area); | 709 | keepInArea(area, partial_keep_in_area); | ||
Show All 38 Lines | 746 | if (session) { | |||
747 | // I.e. obey only forcing rules | 748 | // I.e. obey only forcing rules | ||
748 | setKeepAbove(session->keepAbove); | 749 | setKeepAbove(session->keepAbove); | ||
749 | setKeepBelow(session->keepBelow); | 750 | setKeepBelow(session->keepBelow); | ||
750 | setOriginalSkipTaskbar(session->skipTaskbar); | 751 | setOriginalSkipTaskbar(session->skipTaskbar); | ||
751 | setSkipPager(session->skipPager); | 752 | setSkipPager(session->skipPager); | ||
752 | setSkipSwitcher(session->skipSwitcher); | 753 | setSkipSwitcher(session->skipSwitcher); | ||
753 | setShade(session->shaded ? ShadeNormal : ShadeNone); | 754 | setShade(session->shaded ? ShadeNormal : ShadeNone); | ||
754 | setOpacity(session->opacity); | 755 | setOpacity(session->opacity); | ||
755 | geom_restore = session->restore; | 756 | setGeometryRestore(session->restore); | ||
756 | if (session->maximized != MaximizeRestore) { | 757 | if (session->maximized != MaximizeRestore) { | ||
757 | maximize(MaximizeMode(session->maximized)); | 758 | maximize(MaximizeMode(session->maximized)); | ||
758 | } | 759 | } | ||
759 | if (session->fullscreen != FullScreenNone) { | 760 | if (session->fullscreen != FullScreenNone) { | ||
760 | setFullScreen(true, false); | 761 | setFullScreen(true, false); | ||
761 | geom_fs_restore = session->fsrestore; | 762 | geom_fs_restore = session->fsrestore; | ||
762 | } | 763 | } | ||
763 | checkOffscreenPosition(&geom_restore, area); | 764 | QRect checkedGeometryRestore = geometryRestore(); | ||
765 | checkOffscreenPosition(&checkedGeometryRestore, area); | ||||
764 | checkOffscreenPosition(&geom_fs_restore, area); | 766 | checkOffscreenPosition(&geom_fs_restore, area); | ||
767 | setGeometryRestore(checkedGeometryRestore); | ||||
765 | } else { | 768 | } else { | ||
766 | // Window may want to be maximized | 769 | // Window may want to be maximized | ||
767 | // done after checking that the window isn't larger than the workarea, so that | 770 | // done after checking that the window isn't larger than the workarea, so that | ||
768 | // the restore geometry from the checks above takes precedence, and window | 771 | // the restore geometry from the checks above takes precedence, and window | ||
769 | // isn't restored larger than the workarea | 772 | // isn't restored larger than the workarea | ||
770 | MaximizeMode maxmode = static_cast<MaximizeMode>( | 773 | MaximizeMode maxmode = static_cast<MaximizeMode>( | ||
771 | ((info->state() & NET::MaxVert) ? MaximizeVertical : 0) | | 774 | ((info->state() & NET::MaxVert) ? MaximizeVertical : 0) | | ||
772 | ((info->state() & NET::MaxHoriz) ? MaximizeHorizontal : 0)); | 775 | ((info->state() & NET::MaxHoriz) ? MaximizeHorizontal : 0)); | ||
▲ Show 20 Lines • Show All 3225 Lines • ▼ Show 20 Line(s) | 3997 | if (!from_tool && (!isSpecialWindow() || isToolbar()) && !isFullScreen()) { | |||
3998 | if (area.contains(origClientGeometry)) | 4001 | if (area.contains(origClientGeometry)) | ||
3999 | keepInArea(area); | 4002 | keepInArea(area); | ||
4000 | area = workspace()->clientArea(WorkArea, this); | 4003 | area = workspace()->clientArea(WorkArea, this); | ||
4001 | if (area.contains(origClientGeometry)) | 4004 | if (area.contains(origClientGeometry)) | ||
4002 | keepInArea(area); | 4005 | keepInArea(area); | ||
4003 | } | 4006 | } | ||
4004 | } | 4007 | } | ||
4005 | } | 4008 | } | ||
4006 | geom_restore = frameGeometry(); | 4009 | setGeometryRestore(frameGeometry()); | ||
4007 | // No need to send synthetic configure notify event here, either it's sent together | 4010 | // No need to send synthetic configure notify event here, either it's sent together | ||
4008 | // with geometry change, or there's no need to send it. | 4011 | // with geometry change, or there's no need to send it. | ||
4009 | // Handling of the real ConfigureRequest event forces sending it, as there it's necessary. | 4012 | // Handling of the real ConfigureRequest event forces sending it, as there it's necessary. | ||
4010 | } | 4013 | } | ||
4011 | 4014 | | |||
4012 | void X11Client::resizeWithChecks(int w, int h, xcb_gravity_t gravity, ForceGeometry_t force) | 4015 | void X11Client::resizeWithChecks(int w, int h, xcb_gravity_t gravity, ForceGeometry_t force) | ||
4013 | { | 4016 | { | ||
4014 | Q_ASSERT(!shade_geometry_change); | 4017 | Q_ASSERT(!shade_geometry_change); | ||
▲ Show 20 Lines • Show All 355 Lines • ▼ Show 20 Line(s) | 4318 | { | |||
4370 | // save sizes for restoring, if maximalizing | 4373 | // save sizes for restoring, if maximalizing | ||
4371 | QSize sz; | 4374 | QSize sz; | ||
4372 | if (isShade()) | 4375 | if (isShade()) | ||
4373 | sz = sizeForClientSize(clientSize()); | 4376 | sz = sizeForClientSize(clientSize()); | ||
4374 | else | 4377 | else | ||
4375 | sz = size(); | 4378 | sz = size(); | ||
4376 | 4379 | | |||
4377 | if (quickTileMode() == QuickTileMode(QuickTileFlag::None)) { | 4380 | if (quickTileMode() == QuickTileMode(QuickTileFlag::None)) { | ||
4381 | QRect savedGeometry = geometryRestore(); | ||||
4378 | if (!adjust && !(old_mode & MaximizeVertical)) { | 4382 | if (!adjust && !(old_mode & MaximizeVertical)) { | ||
4379 | geom_restore.setTop(y()); | 4383 | savedGeometry.setTop(y()); | ||
4380 | geom_restore.setHeight(sz.height()); | 4384 | savedGeometry.setHeight(sz.height()); | ||
4381 | } | 4385 | } | ||
4382 | if (!adjust && !(old_mode & MaximizeHorizontal)) { | 4386 | if (!adjust && !(old_mode & MaximizeHorizontal)) { | ||
4383 | geom_restore.setLeft(x()); | 4387 | savedGeometry.setLeft(x()); | ||
4384 | geom_restore.setWidth(sz.width()); | 4388 | savedGeometry.setWidth(sz.width()); | ||
4385 | } | 4389 | } | ||
4390 | setGeometryRestore(savedGeometry); | ||||
4386 | } | 4391 | } | ||
4387 | 4392 | | |||
4388 | // call into decoration update borders | 4393 | // call into decoration update borders | ||
4389 | if (isDecorated() && decoration()->client() && !(options->borderlessMaximizedWindows() && max_mode == KWin::MaximizeFull)) { | 4394 | if (isDecorated() && decoration()->client() && !(options->borderlessMaximizedWindows() && max_mode == KWin::MaximizeFull)) { | ||
4390 | changeMaximizeRecursion = true; | 4395 | changeMaximizeRecursion = true; | ||
4391 | const auto c = decoration()->client().data(); | 4396 | const auto c = decoration()->client().data(); | ||
4392 | if ((max_mode & MaximizeVertical) != (old_mode & MaximizeVertical)) { | 4397 | if ((max_mode & MaximizeVertical) != (old_mode & MaximizeVertical)) { | ||
4393 | emit c->maximizedVerticallyChanged(max_mode & MaximizeVertical); | 4398 | emit c->maximizedVerticallyChanged(max_mode & MaximizeVertical); | ||
Show All 15 Lines | 4409 | if (options->borderlessMaximizedWindows()) { | |||
4409 | changeMaximizeRecursion = false; | 4414 | changeMaximizeRecursion = false; | ||
4410 | } | 4415 | } | ||
4411 | 4416 | | |||
4412 | const ForceGeometry_t geom_mode = isDecorated() ? ForceGeometrySet : NormalGeometrySet; | 4417 | const ForceGeometry_t geom_mode = isDecorated() ? ForceGeometrySet : NormalGeometrySet; | ||
4413 | 4418 | | |||
4414 | // Conditional quick tiling exit points | 4419 | // Conditional quick tiling exit points | ||
4415 | if (quickTileMode() != QuickTileMode(QuickTileFlag::None)) { | 4420 | if (quickTileMode() != QuickTileMode(QuickTileFlag::None)) { | ||
4416 | if (old_mode == MaximizeFull && | 4421 | if (old_mode == MaximizeFull && | ||
4417 | !clientArea.contains(geom_restore.center())) { | 4422 | !clientArea.contains(geometryRestore().center())) { | ||
4418 | // Not restoring on the same screen | 4423 | // Not restoring on the same screen | ||
4419 | // TODO: The following doesn't work for some reason | 4424 | // TODO: The following doesn't work for some reason | ||
4420 | //quick_tile_mode = QuickTileFlag::None; // And exit quick tile mode manually | 4425 | //quick_tile_mode = QuickTileFlag::None; // And exit quick tile mode manually | ||
4421 | } else if ((old_mode == MaximizeVertical && max_mode == MaximizeRestore) || | 4426 | } else if ((old_mode == MaximizeVertical && max_mode == MaximizeRestore) || | ||
4422 | (old_mode == MaximizeFull && max_mode == MaximizeHorizontal)) { | 4427 | (old_mode == MaximizeFull && max_mode == MaximizeHorizontal)) { | ||
4423 | // Modifying geometry of a tiled window | 4428 | // Modifying geometry of a tiled window | ||
4424 | updateQuickTileMode(QuickTileFlag::None); // Exit quick tile mode without restoring geometry | 4429 | updateQuickTileMode(QuickTileFlag::None); // Exit quick tile mode without restoring geometry | ||
4425 | } | 4430 | } | ||
4426 | } | 4431 | } | ||
4427 | 4432 | | |||
4428 | switch(max_mode) { | 4433 | switch(max_mode) { | ||
4429 | 4434 | | |||
4430 | case MaximizeVertical: { | 4435 | case MaximizeVertical: { | ||
4431 | if (old_mode & MaximizeHorizontal) { // actually restoring from MaximizeFull | 4436 | if (old_mode & MaximizeHorizontal) { // actually restoring from MaximizeFull | ||
4432 | if (geom_restore.width() == 0 || !clientArea.contains(geom_restore.center())) { | 4437 | if (geometryRestore().width() == 0 || !clientArea.contains(geometryRestore().center())) { | ||
4433 | // needs placement | 4438 | // needs placement | ||
4434 | plainResize(adjustedSize(QSize(width() * 2 / 3, clientArea.height()), SizeModeFixedH), geom_mode); | 4439 | plainResize(adjustedSize(QSize(width() * 2 / 3, clientArea.height()), SizeModeFixedH), geom_mode); | ||
4435 | Placement::self()->placeSmart(this, clientArea); | 4440 | Placement::self()->placeSmart(this, clientArea); | ||
4436 | } else { | 4441 | } else { | ||
4437 | setFrameGeometry(QRect(QPoint(geom_restore.x(), clientArea.top()), | 4442 | setFrameGeometry(QRect(QPoint(geometryRestore().x(), clientArea.top()), | ||
4438 | adjustedSize(QSize(geom_restore.width(), clientArea.height()), SizeModeFixedH)), geom_mode); | 4443 | adjustedSize(QSize(geometryRestore().width(), clientArea.height()), SizeModeFixedH)), geom_mode); | ||
4439 | } | 4444 | } | ||
4440 | } else { | 4445 | } else { | ||
4441 | QRect r(x(), clientArea.top(), width(), clientArea.height()); | 4446 | QRect r(x(), clientArea.top(), width(), clientArea.height()); | ||
4442 | r.setTopLeft(rules()->checkPosition(r.topLeft())); | 4447 | r.setTopLeft(rules()->checkPosition(r.topLeft())); | ||
4443 | r.setSize(adjustedSize(r.size(), SizeModeFixedH)); | 4448 | r.setSize(adjustedSize(r.size(), SizeModeFixedH)); | ||
4444 | setFrameGeometry(r, geom_mode); | 4449 | setFrameGeometry(r, geom_mode); | ||
4445 | } | 4450 | } | ||
4446 | info->setState(NET::MaxVert, NET::Max); | 4451 | info->setState(NET::MaxVert, NET::Max); | ||
4447 | break; | 4452 | break; | ||
4448 | } | 4453 | } | ||
4449 | 4454 | | |||
4450 | case MaximizeHorizontal: { | 4455 | case MaximizeHorizontal: { | ||
4451 | if (old_mode & MaximizeVertical) { // actually restoring from MaximizeFull | 4456 | if (old_mode & MaximizeVertical) { // actually restoring from MaximizeFull | ||
4452 | if (geom_restore.height() == 0 || !clientArea.contains(geom_restore.center())) { | 4457 | if (geometryRestore().height() == 0 || !clientArea.contains(geometryRestore().center())) { | ||
4453 | // needs placement | 4458 | // needs placement | ||
4454 | plainResize(adjustedSize(QSize(clientArea.width(), height() * 2 / 3), SizeModeFixedW), geom_mode); | 4459 | plainResize(adjustedSize(QSize(clientArea.width(), height() * 2 / 3), SizeModeFixedW), geom_mode); | ||
4455 | Placement::self()->placeSmart(this, clientArea); | 4460 | Placement::self()->placeSmart(this, clientArea); | ||
4456 | } else { | 4461 | } else { | ||
4457 | setFrameGeometry(QRect(QPoint(clientArea.left(), geom_restore.y()), | 4462 | setFrameGeometry(QRect(QPoint(clientArea.left(), geometryRestore().y()), | ||
4458 | adjustedSize(QSize(clientArea.width(), geom_restore.height()), SizeModeFixedW)), geom_mode); | 4463 | adjustedSize(QSize(clientArea.width(), geometryRestore().height()), SizeModeFixedW)), geom_mode); | ||
4459 | } | 4464 | } | ||
4460 | } else { | 4465 | } else { | ||
4461 | QRect r(clientArea.left(), y(), clientArea.width(), height()); | 4466 | QRect r(clientArea.left(), y(), clientArea.width(), height()); | ||
4462 | r.setTopLeft(rules()->checkPosition(r.topLeft())); | 4467 | r.setTopLeft(rules()->checkPosition(r.topLeft())); | ||
4463 | r.setSize(adjustedSize(r.size(), SizeModeFixedW)); | 4468 | r.setSize(adjustedSize(r.size(), SizeModeFixedW)); | ||
4464 | setFrameGeometry(r, geom_mode); | 4469 | setFrameGeometry(r, geom_mode); | ||
4465 | } | 4470 | } | ||
4466 | info->setState(NET::MaxHoriz, NET::Max); | 4471 | info->setState(NET::MaxHoriz, NET::Max); | ||
4467 | break; | 4472 | break; | ||
4468 | } | 4473 | } | ||
4469 | 4474 | | |||
4470 | case MaximizeRestore: { | 4475 | case MaximizeRestore: { | ||
4471 | QRect restore = frameGeometry(); | 4476 | QRect restore = frameGeometry(); | ||
4472 | // when only partially maximized, geom_restore may not have the other dimension remembered | 4477 | // when only partially maximized, geom_restore may not have the other dimension remembered | ||
4473 | if (old_mode & MaximizeVertical) { | 4478 | if (old_mode & MaximizeVertical) { | ||
4474 | restore.setTop(geom_restore.top()); | 4479 | restore.setTop(geometryRestore().top()); | ||
4475 | restore.setBottom(geom_restore.bottom()); | 4480 | restore.setBottom(geometryRestore().bottom()); | ||
4476 | } | 4481 | } | ||
4477 | if (old_mode & MaximizeHorizontal) { | 4482 | if (old_mode & MaximizeHorizontal) { | ||
4478 | restore.setLeft(geom_restore.left()); | 4483 | restore.setLeft(geometryRestore().left()); | ||
4479 | restore.setRight(geom_restore.right()); | 4484 | restore.setRight(geometryRestore().right()); | ||
4480 | } | 4485 | } | ||
4481 | if (!restore.isValid()) { | 4486 | if (!restore.isValid()) { | ||
4482 | QSize s = QSize(clientArea.width() * 2 / 3, clientArea.height() * 2 / 3); | 4487 | QSize s = QSize(clientArea.width() * 2 / 3, clientArea.height() * 2 / 3); | ||
4483 | if (geom_restore.width() > 0) | 4488 | if (geometryRestore().width() > 0) { | ||
4484 | s.setWidth(geom_restore.width()); | 4489 | s.setWidth(geometryRestore().width()); | ||
4485 | if (geom_restore.height() > 0) | 4490 | } | ||
4486 | s.setHeight(geom_restore.height()); | 4491 | if (geometryRestore().height() > 0) { | ||
4492 | s.setHeight(geometryRestore().height()); | ||||
4493 | } | ||||
4487 | plainResize(adjustedSize(s)); | 4494 | plainResize(adjustedSize(s)); | ||
4488 | Placement::self()->placeSmart(this, clientArea); | 4495 | Placement::self()->placeSmart(this, clientArea); | ||
4489 | restore = frameGeometry(); | 4496 | restore = frameGeometry(); | ||
4490 | if (geom_restore.width() > 0) | 4497 | if (geometryRestore().width() > 0) { | ||
4491 | restore.moveLeft(geom_restore.x()); | 4498 | restore.moveLeft(geometryRestore().x()); | ||
4492 | if (geom_restore.height() > 0) | 4499 | } | ||
4493 | restore.moveTop(geom_restore.y()); | 4500 | if (geometryRestore().height() > 0) { | ||
4494 | geom_restore = restore; // relevant for mouse pos calculation, bug #298646 | 4501 | restore.moveTop(geometryRestore().y()); | ||
4502 | } | ||||
4503 | setGeometryRestore(restore); // relevant for mouse pos calculation, bug #298646 | ||||
4495 | } | 4504 | } | ||
4496 | if (m_geometryHints.hasAspect()) { | 4505 | if (m_geometryHints.hasAspect()) { | ||
4497 | restore.setSize(adjustedSize(restore.size(), SizeModeAny)); | 4506 | restore.setSize(adjustedSize(restore.size(), SizeModeAny)); | ||
4498 | } | 4507 | } | ||
4499 | setFrameGeometry(restore, geom_mode); | 4508 | setFrameGeometry(restore, geom_mode); | ||
4500 | if (!clientArea.contains(geom_restore.center())) // Not restoring to the same screen | 4509 | if (!clientArea.contains(geometryRestore().center())) { // Not restoring to the same screen | ||
4501 | Placement::self()->place(this, clientArea); | 4510 | Placement::self()->place(this, clientArea); | ||
4511 | } | ||||
4502 | info->setState(NET::States(), NET::Max); | 4512 | info->setState(NET::States(), NET::Max); | ||
4503 | updateQuickTileMode(QuickTileFlag::None); | 4513 | updateQuickTileMode(QuickTileFlag::None); | ||
4504 | break; | 4514 | break; | ||
4505 | } | 4515 | } | ||
4506 | 4516 | | |||
4507 | case MaximizeFull: { | 4517 | case MaximizeFull: { | ||
4508 | QRect r(clientArea); | 4518 | QRect r(clientArea); | ||
4509 | r.setTopLeft(rules()->checkPosition(r.topLeft())); | 4519 | r.setTopLeft(rules()->checkPosition(r.topLeft())); | ||
▲ Show 20 Lines • Show All 492 Lines • Show Last 20 Lines |