fix untabbing position
the geometry setting needs to happen out of recursion, has to be smarter for unmaximizing and also no real place in TabGroup - the client is no longer tabbed thus it's not the groups task to manage it's geometry. BUG: 226881 REVIEW: 106182 FIXED-IN: 4.9.1
This commit is contained in:
parent
a6296dda20
commit
3460d5b551
6 changed files with 44 additions and 22 deletions
26
client.cpp
26
client.cpp
|
@ -1940,11 +1940,35 @@ bool Client::tabTo(Client *other, bool behind, bool activate)
|
||||||
bool Client::untab(const QRect &toGeometry)
|
bool Client::untab(const QRect &toGeometry)
|
||||||
{
|
{
|
||||||
TabGroup *group = tab_group;
|
TabGroup *group = tab_group;
|
||||||
if (group && group->remove(this, toGeometry)) { // remove sets the tabgroup to "0", therefore the pointer is cached
|
if (group && group->remove(this)) { // remove sets the tabgroup to "0", therefore the pointer is cached
|
||||||
if (group->isEmpty()) {
|
if (group->isEmpty()) {
|
||||||
delete group;
|
delete group;
|
||||||
}
|
}
|
||||||
setClientShown(!(isMinimized() || isShade()));
|
setClientShown(!(isMinimized() || isShade()));
|
||||||
|
bool keepSize = toGeometry.size() == size();
|
||||||
|
bool changedSize = false;
|
||||||
|
if (quickTileMode() != QuickTileNone) {
|
||||||
|
changedSize = true;
|
||||||
|
setQuickTileMode(QuickTileNone); // if we leave a quicktiled group, assume that the user wants to untile
|
||||||
|
}
|
||||||
|
if (toGeometry.isValid()) {
|
||||||
|
if (maximizeMode() != Client::MaximizeRestore) {
|
||||||
|
changedSize = true;
|
||||||
|
maximize(Client::MaximizeRestore); // explicitly calling for a geometry -> unmaximize
|
||||||
|
}
|
||||||
|
if (keepSize && changedSize) {
|
||||||
|
geom_restore = geometry(); // checkWorkspacePosition() invokes it
|
||||||
|
QPoint cpoint = QCursor::pos();
|
||||||
|
QPoint point = cpoint;
|
||||||
|
point.setX((point.x() - toGeometry.x()) * geom_restore.width() / toGeometry.width());
|
||||||
|
point.setY((point.y() - toGeometry.y()) * geom_restore.height() / toGeometry.height());
|
||||||
|
geom_restore.moveTo(cpoint-point);
|
||||||
|
} else {
|
||||||
|
geom_restore = toGeometry; // checkWorkspacePosition() invokes it
|
||||||
|
}
|
||||||
|
setGeometry(geom_restore);
|
||||||
|
checkWorkspacePosition();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -319,6 +319,12 @@ void Placement::reinitCascading(int desktop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPoint Workspace::cascadeOffset(const Client *c) const
|
||||||
|
{
|
||||||
|
QRect area = clientArea(PlacementArea, c->geometry().center(), c->desktop());
|
||||||
|
return QPoint(area.width()/48, area.height()/48);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Place windows in a cascading order, remembering positions for each desktop
|
Place windows in a cascading order, remembering positions for each desktop
|
||||||
*/
|
*/
|
||||||
|
@ -330,8 +336,7 @@ void Placement::placeCascaded(Client* c, QRect& area, Policy nextPlacement)
|
||||||
int xp, yp;
|
int xp, yp;
|
||||||
|
|
||||||
//CT how do I get from the 'Client' class the size that NW squarish "handle"
|
//CT how do I get from the 'Client' class the size that NW squarish "handle"
|
||||||
const int delta_x = 24;
|
const QPoint delta = m_WorkspacePtr->cascadeOffset(c);
|
||||||
const int delta_y = 24;
|
|
||||||
|
|
||||||
const int dn = c->desktop() == 0 || c->isOnAllDesktops() ? (m_WorkspacePtr->currentDesktop() - 1) : (c->desktop() - 1);
|
const int dn = c->desktop() == 0 || c->isOnAllDesktops() ? (m_WorkspacePtr->currentDesktop() - 1) : (c->desktop() - 1);
|
||||||
|
|
||||||
|
@ -375,16 +380,16 @@ void Placement::placeCascaded(Client* c, QRect& area, Policy nextPlacement)
|
||||||
* egcs-2.91.66 on SuSE Linux 6.3. The equivalent forms compile fine.
|
* egcs-2.91.66 on SuSE Linux 6.3. The equivalent forms compile fine.
|
||||||
* 22-Dec-1999 CS
|
* 22-Dec-1999 CS
|
||||||
*
|
*
|
||||||
* if (xp != X && yp == Y) xp = delta_x * (++(cci[dn].col));
|
* if (xp != X && yp == Y) xp = delta.x() * (++(cci[dn].col));
|
||||||
* if (yp != Y && xp == X) yp = delta_y * (++(cci[dn].row));
|
* if (yp != Y && xp == X) yp = delta.y() * (++(cci[dn].row));
|
||||||
*/
|
*/
|
||||||
if (xp != X && yp == Y) {
|
if (xp != X && yp == Y) {
|
||||||
++(cci[dn].col);
|
++(cci[dn].col);
|
||||||
xp = delta_x * cci[dn].col;
|
xp = delta.x() * cci[dn].col;
|
||||||
}
|
}
|
||||||
if (yp != Y && xp == X) {
|
if (yp != Y && xp == X) {
|
||||||
++(cci[dn].row);
|
++(cci[dn].row);
|
||||||
yp = delta_y * cci[dn].row;
|
yp = delta.y() * cci[dn].row;
|
||||||
}
|
}
|
||||||
|
|
||||||
// last resort: if still doesn't fit, smart place it
|
// last resort: if still doesn't fit, smart place it
|
||||||
|
@ -398,7 +403,7 @@ void Placement::placeCascaded(Client* c, QRect& area, Policy nextPlacement)
|
||||||
c->move(QPoint(xp, yp));
|
c->move(QPoint(xp, yp));
|
||||||
|
|
||||||
// new position
|
// new position
|
||||||
cci[dn].pos = QPoint(xp + delta_x, yp + delta_y);
|
cci[dn].pos = QPoint(xp + delta.x(), yp + delta.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
12
tabgroup.cpp
12
tabgroup.cpp
|
@ -144,7 +144,7 @@ bool TabGroup::add(Client* c, Client *other, bool after, bool becomeVisible)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TabGroup::remove(Client* c, const QRect& newGeom)
|
bool TabGroup::remove(Client* c)
|
||||||
{
|
{
|
||||||
if (!c)
|
if (!c)
|
||||||
return false;
|
return false;
|
||||||
|
@ -159,7 +159,7 @@ bool TabGroup::remove(Client* c, const QRect& newGeom)
|
||||||
updateMinMaxSize();
|
updateMinMaxSize();
|
||||||
|
|
||||||
if (m_clients.count() == 1) { // split
|
if (m_clients.count() == 1) { // split
|
||||||
remove(m_clients.at(0), m_clients.at(0)->geometry());
|
remove(m_clients.at(0));
|
||||||
}
|
}
|
||||||
if (m_clients.isEmpty()) { // remaining singleton "tab"
|
if (m_clients.isEmpty()) { // remaining singleton "tab"
|
||||||
c->setClientShown(true);
|
c->setClientShown(true);
|
||||||
|
@ -174,14 +174,6 @@ bool TabGroup::remove(Client* c, const QRect& newGeom)
|
||||||
static_cast<EffectsHandlerImpl*>(effects)->slotCurrentTabAboutToChange(c->effectWindow(), m_current->effectWindow());
|
static_cast<EffectsHandlerImpl*>(effects)->slotCurrentTabAboutToChange(c->effectWindow(), m_current->effectWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->quickTileMode() != QuickTileNone)
|
|
||||||
c->setQuickTileMode(QuickTileNone); // if we leave a quicktiled group, assume that the user wants to untile
|
|
||||||
else if (newGeom.isValid()) {
|
|
||||||
c->maximize(Client::MaximizeRestore); // explicitly calling for a geometry -> unmaximize - in doubt
|
|
||||||
c->setGeometry(newGeom);
|
|
||||||
c->checkWorkspacePosition(); // oxygen has now twice kicked me a window out of the screen - better be safe then sorry
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify effects of removal
|
// Notify effects of removal
|
||||||
if (effects)
|
if (effects)
|
||||||
static_cast<EffectsHandlerImpl*>(effects)->slotTabRemoved(c->effectWindow(), m_current->effectWindow());
|
static_cast<EffectsHandlerImpl*>(effects)->slotTabRemoved(c->effectWindow(), m_current->effectWindow());
|
||||||
|
|
|
@ -157,7 +157,7 @@ private:
|
||||||
void move(KWin::Client* c, KWin::Client* before, bool behind);
|
void move(KWin::Client* c, KWin::Client* before, bool behind);
|
||||||
|
|
||||||
// friend bool Client::untab(const QRect&);
|
// friend bool Client::untab(const QRect&);
|
||||||
bool remove(KWin::Client *c, const QRect &newGeom = QRect());
|
bool remove(KWin::Client *c);
|
||||||
|
|
||||||
ClientList m_clients;
|
ClientList m_clients;
|
||||||
Client *m_current;
|
Client *m_current;
|
||||||
|
|
|
@ -766,8 +766,7 @@ void Workspace::performWindowOperation(Client* c, Options::WindowOperation op)
|
||||||
case Options::NoOp:
|
case Options::NoOp:
|
||||||
break;
|
break;
|
||||||
case Options::RemoveTabFromGroupOp:
|
case Options::RemoveTabFromGroupOp:
|
||||||
if (c->untab())
|
if (c->untab(c->geometry().translated(cascadeOffset(c))) && options->focusPolicyIsReasonable())
|
||||||
if (options->focusPolicyIsReasonable())
|
|
||||||
takeActivity(c, ActivityFocus | ActivityRaise, true);
|
takeActivity(c, ActivityFocus | ActivityRaise, true);
|
||||||
break;
|
break;
|
||||||
case Options::ActivateNextTabOp:
|
case Options::ActivateNextTabOp:
|
||||||
|
@ -1424,7 +1423,7 @@ void Workspace::slotActivatePrevTab()
|
||||||
void Workspace::slotUntab()
|
void Workspace::slotUntab()
|
||||||
{
|
{
|
||||||
if (active_client)
|
if (active_client)
|
||||||
active_client->untab();
|
active_client->untab(active_client->geometry().translated(cascadeOffset(active_client)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -301,6 +301,8 @@ public:
|
||||||
*/
|
*/
|
||||||
int desktopToLeft(int id = 0, bool wrap = true) const;
|
int desktopToLeft(int id = 0, bool wrap = true) const;
|
||||||
|
|
||||||
|
QPoint cascadeOffset(const Client *c) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int desktopCount_;
|
int desktopCount_;
|
||||||
QSize desktopGridSize_;
|
QSize desktopGridSize_;
|
||||||
|
|
Loading…
Reference in a new issue