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 QRect KWinGrid::doMoveResize(int __xslot, int __yslot,
153 int __xsize, int __ysize)
155 QRect newGeometry(outer_);
158 __xsize = (outer_.width()+hsize_/2)/hsize_;
159 if (__xsize<1) __xsize = 1;
160 if (__xsize>hsplit_) __xsize = hsplit_;
163 __ysize = (outer_.height()+vsize_/2)/vsize_;
164 if (__ysize<1) __ysize = 1;
165 if (__ysize>vsplit_) __ysize = vsplit_;
168 newGeometry.setWidth(__xsize*hsize_-hgap_);
169 newGeometry.setHeight(__ysize*vsize_-vgap_);
172 __xslot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
173 if (__xslot<0) __xslot = 0;
174 if (__xslot>=hsplit_) __xslot = hsplit_-1;
177 __yslot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
178 if (__yslot<0) __yslot = 0;
179 if (__yslot>=vsplit_) __yslot = vsplit_-1;
181 newGeometry.moveTopLeft(QPoint(region_.left() + __xslot*hsize_ + hgap_/2,
182 region_.top() + __yslot*vsize_ + vgap_/2));
186 std::ostream& operator<<(std::ostream& os, QRect rect)
188 os << '(' << rect.width() << 'x' << rect.height() << '+' << rect.x() << '+' << rect.y() << ')';
192 std::ostream& operator<<(std::ostream& os, QPoint p)
194 os << '(' << p.x() << ',' << p.y() << ')';
198 std::ostream& operator<<(std::ostream& os, QSize s)
200 os << '(' << s.width() << 'x' << s.height() << ')';
204 void KWinGrid::initGeometry(int __forceScreen)
206 activeWindowChanged(0);
207 if (activeWindow_ == 0)
208 activeWindow_ = activeWindow();
210 KWindowInfo info(KWindowSystem::windowInfo(activeWindow_,NET::WMGeometry|NET::WMFrameExtents));
211 inner_ = info.geometry();
212 outer_ = info.frameGeometry();
215 if (__forceScreen == -1)
216 screen_ = outer_.left()>=split_ ? 1 : 0;
218 screen_ = __forceScreen;
219 region_ = QApplication::desktop()->screenGeometry();
221 region_.setLeft(split_);
223 region_.setRight(split_-1);
226 if (__forceScreen == -1)
227 screen_ = QApplication::desktop()->screenNumber(outer_.topLeft());
229 screen_ = __forceScreen;
230 region_ = QApplication::desktop()->screenGeometry(screen_);
231 // region_ = QApplication::desktop()->availableGeometry(screen_);
232 numScreens_ = QApplication::desktop()->numScreens();
234 if (screen_ != ignorestruts_ && ignorestruts_ != -1) {
235 QRect wa = KWindowSystem::workArea();
236 region_ = region_ & wa;
238 if (screen_ == strutscreen_ || strutscreen_ == -1) {
239 region_.setHeight(region_.height() - southstrut_);
242 hsize_ = (region_.width()-hgap_)/hsplit_;
243 vsize_ = (region_.height()-vgap_)/vsplit_;
245 int hdelta = region_.width()-hsize_*hsplit_;
246 int vdelta = region_.height()-vsize_*vsplit_;
247 QPoint topLeft(region_.topLeft());
248 topLeft+=QPoint(hdelta/2,vdelta/2);
249 region_.moveTopLeft(topLeft);
250 region_.setSize(QSize(hsize_*hsplit_,vsize_*vsplit_));
253 if (XGetWMNormalHints(QX11Info::display(), activeWindow_, &hints_, &supplied))
254 hints_.flags &= supplied;
260 void KWinGrid::updateGeometry(QRect& __new)
262 QRect newInner(inner_);
263 newInner.moveTopLeft(QPoint(__new.left()+(inner_.left()-outer_.left()),
264 __new.top()+(inner_.top()-outer_.top())));
265 newInner.setSize(QSize(__new.width()-(outer_.width()-inner_.width()),
266 __new.height()-(outer_.height()-inner_.height())));
270 if (hints_.flags & PResizeInc && hints_.width_inc != 0 && hints_.height_inc != 0) {
272 if (hints_.flags & PBaseSize) {
273 base.setWidth(hints_.base_width);
274 base.setHeight(hints_.base_height);
275 } else if (hints_.flags & PMinSize) {
276 base.setWidth(hints_.min_width);
277 base.setHeight(hints_.min_height);
279 QSize newSize(((inner_.width()-base.width())/hints_.width_inc)*hints_.width_inc
281 ((inner_.height()-base.height())/hints_.height_inc)*hints_.height_inc
283 QSize delta(inner_.size() - newSize);
284 QPoint offset(delta.width()/2,delta.height()/2);
285 inner_.setSize(newSize);
286 outer_.setSize(outer_.size() - delta);
287 inner_.moveTopLeft(inner_.topLeft() + offset);
288 outer_.moveTopLeft(outer_.topLeft() + offset);
292 void KWinGrid::applyGeometry()
295 KWindowSystem::clearState(activeWindow_, NET::MaxVert | NET::MaxHoriz | NET::FullScreen);
296 if (orig_.topLeft() == outer_.topLeft())
297 // If the position of the window did not change,
298 // XMoveResizeWindow sometimes still moves the window a little
299 // bit. Seems to have something todo with window gravity
300 // ... we just leave the position allone in that case.
301 XResizeWindow(QX11Info::display(),activeWindow_, inner_.width(),inner_.height());
303 // I don't really know, whats all this stuff concerning window
304 // gravity. I only know, this works for my openoffice windows,
305 // which have StaticGravity. I have not found any window with
306 // a window_gravity of neither StaticGravity nor
307 // NorthWestGravity on my desktop so did not check other
309 QPoint pos = outer_.topLeft();
310 if (hints_.flags & PWinGravity && hints_.win_gravity == StaticGravity)
311 pos = inner_.topLeft();
312 XMoveResizeWindow(QX11Info::display(),activeWindow_,
313 pos.x(),pos.y(), inner_.width(),inner_.height());
317 void KWinGrid::moveSlot(int nx, int ny, int posx, int posy)
319 move((hsplit_-reserveWest_-reserveEast_)/nx * posx + reserveWest_,
320 (vsplit_-reserveNorth_-reserveSouth_)/ny * posy + reserveNorth_);
323 void KWinGrid::resizeSlot(int nx, int ny, int szx, int szy)
325 resize((hsplit_-reserveWest_-reserveEast_)/nx * (szx+1),
326 (vsplit_-reserveNorth_-reserveSouth_)/ny * (szy+1));
331 void KWinGrid::move_TL()
333 moveSlot(2, 2, 0, 0);
336 void KWinGrid::move_TR()
338 moveSlot(2, 2, 1, 0);
341 void KWinGrid::move_BL()
343 moveSlot(2, 2, 0, 1);
346 void KWinGrid::move_BR()
348 moveSlot(2, 2, 1, 1);
351 void KWinGrid::resize_Q()
353 resizeSlot(2, 2, 0, 0);
356 void KWinGrid::resize_H()
358 resizeSlot(2, 2, 1, 0);
361 void KWinGrid::resize_V()
363 resizeSlot(2, 2, 0, 1);
366 void KWinGrid::resize_F()
368 resizeSlot(2, 2, 1, 1);
371 void KWinGrid::move_00()
373 moveSlot(3, 2, 0, 0);
376 void KWinGrid::move_10()
378 moveSlot(3, 2, 1, 0);
381 void KWinGrid::move_20()
383 moveSlot(3, 2, 2, 0);
386 void KWinGrid::move_01()
388 moveSlot(3, 2, 0, 1);
391 void KWinGrid::move_11()
393 moveSlot(3, 2, 1, 1);
396 void KWinGrid::move_21()
398 moveSlot(3, 2, 2, 1);
401 void KWinGrid::resize_00()
403 resizeSlot(3, 2, 0, 0);
406 void KWinGrid::resize_10()
408 resizeSlot(3, 2, 1, 0);
411 void KWinGrid::resize_20()
413 resizeSlot(3, 2, 2, 0);
416 void KWinGrid::resize_01()
418 resizeSlot(3, 2, 0, 1);
421 void KWinGrid::resize_11()
423 resizeSlot(3, 2, 1, 1);
426 void KWinGrid::resize_21()
428 resizeSlot(3, 2, 2, 1);
431 void KWinGrid::move_L()
436 void KWinGrid::move_R()
441 void KWinGrid::move_U()
446 void KWinGrid::move_D()
451 void KWinGrid::resize_IH()
456 void KWinGrid::resize_DH()
458 resizeRelative(-1,0);
461 void KWinGrid::resize_IV()
466 void KWinGrid::resize_DV()
468 resizeRelative(0,-1);