3 #include <QtGui/QDesktopWidget>
4 #include <QtGui/QX11Info>
6 #include <kapplication.h>
7 #include <kwindowsystem.h>
11 #include "kwingrid.moc"
13 KWinGrid::KWinGrid(int hgap__, int vgap__, int hsplit__, int vsplit__, int split__,
14 int ignorestruts__, int reserveNorth__, int reserveSouth__, int reserveWest__, int reserveEast__,
15 int southstrut__, int strutscreen__)
16 : split_(split__), ignorestruts_(ignorestruts__), reserveNorth_(reserveNorth__),
17 reserveSouth_(reserveSouth__), reserveEast_(reserveEast__), reserveWest_(reserveWest__),
18 hgap_(hgap__), vgap_(vgap__), hsplit_(hsplit__), vsplit_(vsplit__),
19 southstrut_(southstrut__), strutscreen_(strutscreen__)
21 connect(KWindowSystem::self(),SIGNAL(activeWindowChanged(WId)),
22 this,SLOT(activeWindowChanged(WId)));
25 void KWinGrid::move(int __xslot, int __yslot)
27 moveResize(__xslot, __yslot, -1, -1);
30 void KWinGrid::resize(int __xsize, int __ysize)
32 moveResize(-1,-1,__xsize,__ysize);
35 void KWinGrid::toDesk(int __desk)
37 int w = activeWindow();
39 KWindowSystem::setOnDesktop(w,__desk);
44 KApplication::kApplication()->quit();
47 int KWinGrid::activeWindow()
49 int av = KWindowSystem::activeWindow();
50 KWindowInfo info = KWindowSystem::windowInfo(av,NET::WMWindowType);
51 if (info.windowType(NET::AllTypesMask) == NET::Desktop) return 0;
55 void KWinGrid::updateTimestamp(void)
57 timestamp_ = QDateTime::currentDateTime();
60 void KWinGrid::activeWindowChanged(WId id)
62 if (!activeWindow_ || timestamp_.isNull())
65 QDateTime tm = QDateTime::currentDateTime();
67 int deltaDays = timestamp_.date().daysTo(tm.date());
68 int deltaMSecs = timestamp_.time().msecsTo(tm.time());
70 if (deltaDays>2 || deltaDays<0) {
75 deltaMSecs += deltaDays * 1000*(60*60*24);
77 if (deltaMSecs <= 500 && deltaMSecs > 0)
78 KWindowSystem::forceActiveWindow(activeWindow_);
83 void KWinGrid::moveResize(int __xslot, int __yslot,
84 int __xsize, int __ysize)
88 QRect newGeometry = doMoveResize(__xslot,__yslot,__xsize,__ysize);
89 updateGeometry(newGeometry);
94 void KWinGrid::moveRelative(int __xdiff, int __ydiff)
98 int xSlot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
99 int ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
103 QPoint p (outer_.topLeft());
104 if (numScreens_ > 1 && p.x() > hsize_) {
106 initGeometry( QApplication::desktop()->screenNumber(p) );
109 } else if (xSlot >= hsplit_) {
110 QPoint p (outer_.topLeft());
111 QRect wa = KWindowSystem::workArea();
112 if (numScreens_ > 1 && p.x() + 2* hsize_ < wa.right()) {
114 initGeometry( QApplication::desktop()->screenNumber(p) );
116 ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_ + __ydiff;
122 else if (ySlot >= vsplit_)
124 QRect newGeometry = doMoveResize(xSlot,ySlot,-1,-1);
125 updateGeometry(newGeometry);
130 void KWinGrid::resizeRelative(int __xdiff, int __ydiff)
134 int xSize = (outer_.width()+hsize_/2)/hsize_;
135 int ySize = (outer_.height()+vsize_/2)/vsize_;
146 QRect newGeometry = doMoveResize(-1,-1,xSize,ySize);
147 updateGeometry(newGeometry);
152 void KWinGrid::toScreen(int screen)
156 int xSize = (outer_.width()+hsize_/2)/hsize_;
157 if (xSize<1) xSize = 1;
158 if (xSize>hsplit_) xSize = hsplit_;
160 int ySize = (outer_.height()+vsize_/2)/vsize_;
161 if (ySize<1) ySize = 1;
162 if (ySize>vsplit_) ySize = vsplit_;
164 int xSlot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
165 if (xSlot<0) xSlot = 0;
166 if (xSlot>=hsplit_) xSlot = hsplit_-1;
168 int ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
169 if (ySlot<0) ySlot = 0;
170 if (ySlot>=vsplit_) ySlot = vsplit_-1;
172 initGeometry(screen);
173 QRect newGeometry = doMoveResize(xSlot,ySlot,xSize,ySize);
174 updateGeometry(newGeometry);
179 QRect KWinGrid::doMoveResize(int __xslot, int __yslot,
180 int __xsize, int __ysize)
182 QRect newGeometry(outer_);
185 __xsize = (outer_.width()+hsize_/2)/hsize_;
186 if (__xsize<1) __xsize = 1;
187 if (__xsize>hsplit_) __xsize = hsplit_;
190 __ysize = (outer_.height()+vsize_/2)/vsize_;
191 if (__ysize<1) __ysize = 1;
192 if (__ysize>vsplit_) __ysize = vsplit_;
195 newGeometry.setWidth(__xsize*hsize_-hgap_);
196 newGeometry.setHeight(__ysize*vsize_-vgap_);
199 __xslot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
200 if (__xslot<0) __xslot = 0;
201 if (__xslot>=hsplit_) __xslot = hsplit_-1;
204 __yslot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
205 if (__yslot<0) __yslot = 0;
206 if (__yslot>=vsplit_) __yslot = vsplit_-1;
208 newGeometry.moveTopLeft(QPoint(region_.left() + __xslot*hsize_ + hgap_/2,
209 region_.top() + __yslot*vsize_ + vgap_/2));
213 std::ostream& operator<<(std::ostream& os, QRect rect)
215 os << '(' << rect.width() << 'x' << rect.height() << '+' << rect.x() << '+' << rect.y() << ')';
219 std::ostream& operator<<(std::ostream& os, QPoint p)
221 os << '(' << p.x() << ',' << p.y() << ')';
225 std::ostream& operator<<(std::ostream& os, QSize s)
227 os << '(' << s.width() << 'x' << s.height() << ')';
231 void KWinGrid::initGeometry(int __forceScreen)
233 activeWindowChanged(0);
234 if (activeWindow_ == 0)
235 activeWindow_ = activeWindow();
237 KWindowInfo info(KWindowSystem::windowInfo(activeWindow_,NET::WMGeometry|NET::WMFrameExtents));
238 inner_ = info.geometry();
239 outer_ = info.frameGeometry();
242 if (__forceScreen == -1)
243 screen_ = outer_.left()>=split_ ? 1 : 0;
245 screen_ = __forceScreen;
246 region_ = QApplication::desktop()->screenGeometry();
248 region_.setLeft(split_);
250 region_.setRight(split_-1);
253 if (__forceScreen == -1)
254 screen_ = QApplication::desktop()->screenNumber(outer_.topLeft());
256 screen_ = __forceScreen;
257 region_ = QApplication::desktop()->screenGeometry(screen_);
258 // region_ = QApplication::desktop()->availableGeometry(screen_);
259 numScreens_ = QApplication::desktop()->numScreens();
261 if (screen_ != ignorestruts_ && ignorestruts_ != -1) {
262 QRect wa = KWindowSystem::workArea();
263 region_ = region_ & wa;
265 if (screen_ == strutscreen_ || strutscreen_ == -1) {
266 region_.setHeight(region_.height() - southstrut_);
269 hsize_ = (region_.width()-hgap_)/hsplit_;
270 vsize_ = (region_.height()-vgap_)/vsplit_;
272 int hdelta = region_.width()-hsize_*hsplit_;
273 int vdelta = region_.height()-vsize_*vsplit_;
274 QPoint topLeft(region_.topLeft());
275 topLeft+=QPoint(hdelta/2,vdelta/2);
276 region_.moveTopLeft(topLeft);
277 region_.setSize(QSize(hsize_*hsplit_,vsize_*vsplit_));
280 if (XGetWMNormalHints(QX11Info::display(), activeWindow_, &hints_, &supplied))
281 hints_.flags &= supplied;
287 void KWinGrid::updateGeometry(QRect& __new)
289 QRect newInner(inner_);
290 newInner.moveTopLeft(QPoint(__new.left()+(inner_.left()-outer_.left()),
291 __new.top()+(inner_.top()-outer_.top())));
292 newInner.setSize(QSize(__new.width()-(outer_.width()-inner_.width()),
293 __new.height()-(outer_.height()-inner_.height())));
297 if (hints_.flags & PResizeInc && hints_.width_inc != 0 && hints_.height_inc != 0) {
299 if (hints_.flags & PBaseSize) {
300 base.setWidth(hints_.base_width);
301 base.setHeight(hints_.base_height);
302 } else if (hints_.flags & PMinSize) {
303 base.setWidth(hints_.min_width);
304 base.setHeight(hints_.min_height);
306 QSize newSize(((inner_.width()-base.width())/hints_.width_inc)*hints_.width_inc
308 ((inner_.height()-base.height())/hints_.height_inc)*hints_.height_inc
310 QSize delta(inner_.size() - newSize);
311 QPoint offset(delta.width()/2,delta.height()/2);
312 inner_.setSize(newSize);
313 outer_.setSize(outer_.size() - delta);
314 inner_.moveTopLeft(inner_.topLeft() + offset);
315 outer_.moveTopLeft(outer_.topLeft() + offset);
319 void KWinGrid::applyGeometry()
322 KWindowSystem::clearState(activeWindow_, NET::MaxVert | NET::MaxHoriz | NET::FullScreen);
323 if (orig_.topLeft() == outer_.topLeft())
324 // If the position of the window did not change,
325 // XMoveResizeWindow sometimes still moves the window a little
326 // bit. Seems to have something todo with window gravity
327 // ... we just leave the position allone in that case.
328 XResizeWindow(QX11Info::display(),activeWindow_, inner_.width(),inner_.height());
330 // I don't really know, whats all this stuff concerning window
331 // gravity. I only know, this works for my openoffice windows,
332 // which have StaticGravity. I have not found any window with
333 // a window_gravity of neither StaticGravity nor
334 // NorthWestGravity on my desktop so did not check other
336 QPoint pos = outer_.topLeft();
337 if (hints_.flags & PWinGravity && hints_.win_gravity == StaticGravity)
338 pos = inner_.topLeft();
339 XMoveResizeWindow(QX11Info::display(),activeWindow_,
340 pos.x(),pos.y(), inner_.width(),inner_.height());
344 void KWinGrid::moveSlot(int nx, int ny, int posx, int posy)
346 move((hsplit_-reserveWest_-reserveEast_)/nx * posx + reserveWest_,
347 (vsplit_-reserveNorth_-reserveSouth_)/ny * posy + reserveNorth_);
350 void KWinGrid::resizeSlot(int nx, int ny, int szx, int szy)
352 resize((hsplit_-reserveWest_-reserveEast_)/nx * (szx+1),
353 (vsplit_-reserveNorth_-reserveSouth_)/ny * (szy+1));
358 void KWinGrid::move_TL() { moveSlot(2, 2, 0, 0); }
359 void KWinGrid::move_TR() { moveSlot(2, 2, 1, 0); }
360 void KWinGrid::move_BL() { moveSlot(2, 2, 0, 1); }
361 void KWinGrid::move_BR() { moveSlot(2, 2, 1, 1); }
362 void KWinGrid::resize_Q() { resizeSlot(2, 2, 0, 0); }
363 void KWinGrid::resize_H() { resizeSlot(2, 2, 1, 0); }
364 void KWinGrid::resize_V() { resizeSlot(2, 2, 0, 1); }
365 void KWinGrid::resize_F() { resizeSlot(2, 2, 1, 1); }
367 void KWinGrid::move32_00() { moveSlot(3, 2, 0, 0); }
368 void KWinGrid::move32_10() { moveSlot(3, 2, 1, 0); }
369 void KWinGrid::move32_20() { moveSlot(3, 2, 2, 0); }
370 void KWinGrid::move32_01() { moveSlot(3, 2, 0, 1); }
371 void KWinGrid::move32_11() { moveSlot(3, 2, 1, 1); }
372 void KWinGrid::move32_21() { moveSlot(3, 2, 2, 1); }
373 void KWinGrid::resize32_00() { resizeSlot(3, 2, 0, 0); }
374 void KWinGrid::resize32_10() { resizeSlot(3, 2, 1, 0); }
375 void KWinGrid::resize32_20() { resizeSlot(3, 2, 2, 0); }
376 void KWinGrid::resize32_01() { resizeSlot(3, 2, 0, 1); }
377 void KWinGrid::resize32_11() { resizeSlot(3, 2, 1, 1); }
378 void KWinGrid::resize32_21() { resizeSlot(3, 2, 2, 1); }
380 void KWinGrid::move43_00() { moveSlot(4, 3, 0, 0); }
381 void KWinGrid::move43_10() { moveSlot(4, 3, 1, 0); }
382 void KWinGrid::move43_20() { moveSlot(4, 3, 2, 0); }
383 void KWinGrid::move43_30() { moveSlot(4, 3, 3, 0); }
384 void KWinGrid::move43_01() { moveSlot(4, 3, 0, 1); }
385 void KWinGrid::move43_11() { moveSlot(4, 3, 1, 1); }
386 void KWinGrid::move43_21() { moveSlot(4, 3, 2, 1); }
387 void KWinGrid::move43_31() { moveSlot(4, 3, 3, 1); }
388 void KWinGrid::move43_02() { moveSlot(4, 3, 0, 2); }
389 void KWinGrid::move43_12() { moveSlot(4, 3, 1, 2); }
390 void KWinGrid::move43_22() { moveSlot(4, 3, 2, 2); }
391 void KWinGrid::move43_32() { moveSlot(4, 3, 3, 2); }
392 void KWinGrid::resize43_00() { resizeSlot(4, 3, 0, 0); }
393 void KWinGrid::resize43_10() { resizeSlot(4, 3, 1, 0); }
394 void KWinGrid::resize43_20() { resizeSlot(4, 3, 2, 0); }
395 void KWinGrid::resize43_30() { resizeSlot(4, 3, 3, 0); }
396 void KWinGrid::resize43_01() { resizeSlot(4, 3, 0, 1); }
397 void KWinGrid::resize43_11() { resizeSlot(4, 3, 1, 1); }
398 void KWinGrid::resize43_21() { resizeSlot(4, 3, 2, 1); }
399 void KWinGrid::resize43_31() { resizeSlot(4, 3, 3, 1); }
400 void KWinGrid::resize43_02() { resizeSlot(4, 3, 0, 2); }
401 void KWinGrid::resize43_12() { resizeSlot(4, 3, 1, 2); }
402 void KWinGrid::resize43_22() { resizeSlot(4, 3, 2, 2); }
403 void KWinGrid::resize43_32() { resizeSlot(4, 3, 3, 2); }
405 void KWinGrid::move_L() { moveRelative(-1,0); }
406 void KWinGrid::move_R() { moveRelative(1,0); }
407 void KWinGrid::move_U() { moveRelative(0,-1); }
408 void KWinGrid::move_D() { moveRelative(0,1); }
409 void KWinGrid::resize_IH() { resizeRelative(1,0); }
410 void KWinGrid::resize_DH() { resizeRelative(-1,0); }
411 void KWinGrid::resize_IV() { resizeRelative(0,1); }
412 void KWinGrid::resize_DV() { resizeRelative(0,-1); }
414 void KWinGrid::move_Screen0() { toScreen(0); }
415 void KWinGrid::move_Screen1() { toScreen(1); }