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__,
15 int reserveWest__, int reserveEast__)
16 : split_(split__), ignorestruts_(ignorestruts__), reserveNorth_(reserveNorth__),
17 reserveSouth_(reserveSouth__), reserveEast_(reserveEast__), reserveWest_(reserveWest__),
18 hgap_(hgap__), vgap_(vgap__), hsplit_(hsplit__), vsplit_(vsplit__)
20 connect(KWindowSystem::self(),SIGNAL(activeWindowChanged(WId)),
21 this,SLOT(activeWindowChanged(WId)));
24 void KWinGrid::move(int __xslot, int __yslot)
26 moveResize(__xslot, __yslot, -1, -1);
29 void KWinGrid::resize(int __xsize, int __ysize)
31 moveResize(-1,-1,__xsize,__ysize);
34 void KWinGrid::toDesk(int __desk)
36 int w = activeWindow();
38 KWindowSystem::setOnDesktop(w,__desk);
43 KApplication::kApplication()->quit();
46 int KWinGrid::activeWindow()
48 int av = KWindowSystem::activeWindow();
49 KWindowInfo info = KWindowSystem::windowInfo(av,NET::WMWindowType);
50 if (info.windowType(NET::AllTypesMask) == NET::Desktop) return 0;
54 void KWinGrid::updateTimestamp(void)
56 timestamp_ = QDateTime::currentDateTime();
59 void KWinGrid::activeWindowChanged(WId id)
61 if (!activeWindow_ || timestamp_.isNull())
64 QDateTime tm = QDateTime::currentDateTime();
66 int deltaDays = timestamp_.date().daysTo(tm.date());
67 int deltaMSecs = timestamp_.time().msecsTo(tm.time());
69 if (deltaDays>2 || deltaDays<0) {
74 deltaMSecs += deltaDays * 1000*(60*60*24);
76 if (deltaMSecs <= 1000 && deltaMSecs > 0)
77 KWindowSystem::forceActiveWindow(activeWindow_);
82 void KWinGrid::moveResize(int __xslot, int __yslot,
83 int __xsize, int __ysize)
87 QRect newGeometry = doMoveResize(__xslot,__yslot,__xsize,__ysize);
88 updateGeometry(newGeometry);
93 void KWinGrid::moveRelative(int __xdiff, int __ydiff)
97 int xSlot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
98 int ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
102 QPoint p (outer_.topLeft());
103 if (numScreens_ > 1 && p.x() > hsize_) {
105 initGeometry( QApplication::desktop()->screenNumber(p) );
108 } else if (xSlot >= hsplit_) {
109 QPoint p (outer_.topLeft());
110 QRect wa = KWindowSystem::workArea();
111 if (numScreens_ > 1 && p.x() + 2* hsize_ < wa.right()) {
113 initGeometry( QApplication::desktop()->screenNumber(p) );
115 ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_ + __ydiff;
121 else if (ySlot >= vsplit_)
123 QRect newGeometry = doMoveResize(xSlot,ySlot,-1,-1);
124 updateGeometry(newGeometry);
129 void KWinGrid::resizeRelative(int __xdiff, int __ydiff)
133 int xSize = (outer_.width()+hsize_/2)/hsize_;
134 int ySize = (outer_.height()+vsize_/2)/vsize_;
145 QRect newGeometry = doMoveResize(-1,-1,xSize,ySize);
146 updateGeometry(newGeometry);
151 QRect KWinGrid::doMoveResize(int __xslot, int __yslot,
152 int __xsize, int __ysize)
154 QRect newGeometry(outer_);
157 __xsize = (outer_.width()+hsize_/2)/hsize_;
158 if (__xsize<1) __xsize = 1;
159 if (__xsize>hsplit_) __xsize = hsplit_;
162 __ysize = (outer_.height()+vsize_/2)/vsize_;
163 if (__ysize<1) __ysize = 1;
164 if (__ysize>vsplit_) __ysize = vsplit_;
167 newGeometry.setWidth(__xsize*hsize_-hgap_);
168 newGeometry.setHeight(__ysize*vsize_-vgap_);
171 __xslot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
172 if (__xslot<0) __xslot = 0;
173 if (__xslot>=hsplit_) __xslot = hsplit_-1;
176 __yslot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
177 if (__yslot<0) __yslot = 0;
178 if (__yslot>=vsplit_) __yslot = vsplit_-1;
180 newGeometry.moveTopLeft(QPoint(region_.left() + __xslot*hsize_ + hgap_/2,
181 region_.top() + __yslot*vsize_ + vgap_/2));
185 std::ostream& operator<<(std::ostream& os, QRect rect)
187 os << '(' << rect.width() << 'x' << rect.height() << '+' << rect.x() << '+' << rect.y() << ')';
191 std::ostream& operator<<(std::ostream& os, QPoint p)
193 os << '(' << p.x() << ',' << p.y() << ')';
197 std::ostream& operator<<(std::ostream& os, QSize s)
199 os << '(' << s.width() << 'x' << s.height() << ')';
203 void KWinGrid::initGeometry(int __forceScreen)
205 activeWindowChanged(0);
206 if (activeWindow_ == 0)
207 activeWindow_ = activeWindow();
209 KWindowInfo info(KWindowSystem::windowInfo(activeWindow_,NET::WMGeometry|NET::WMFrameExtents));
210 inner_ = info.geometry();
211 outer_ = info.frameGeometry();
214 if (__forceScreen == -1)
215 screen_ = outer_.left()>=split_ ? 1 : 0;
217 screen_ = __forceScreen;
218 region_ = QApplication::desktop()->screenGeometry();
220 region_.setLeft(split_);
222 region_.setRight(split_-1);
225 if (__forceScreen == -1)
226 screen_ = QApplication::desktop()->screenNumber(outer_.topLeft());
228 screen_ = __forceScreen;
229 region_ = QApplication::desktop()->screenGeometry(screen_);
230 numScreens_ = QApplication::desktop()->numScreens();
232 if (screen_ != ignorestruts_) {
233 QRect wa = KWindowSystem::workArea();
234 region_ = region_ & wa;
237 hsize_ = (region_.width()-hgap_)/hsplit_;
238 vsize_ = (region_.height()-vgap_)/vsplit_;
240 int hdelta = region_.width()-hsize_*hsplit_;
241 int vdelta = region_.height()-vsize_*vsplit_;
242 QPoint topLeft(region_.topLeft());
243 topLeft+=QPoint(hdelta/2,vdelta/2);
244 region_.moveTopLeft(topLeft);
245 region_.setSize(QSize(hsize_*hsplit_,vsize_*vsplit_));
248 if (XGetWMNormalHints(QX11Info::display(), activeWindow_, &hints_, &supplied))
249 hints_.flags &= supplied;
255 void KWinGrid::updateGeometry(QRect& __new)
257 QRect newInner(inner_);
258 newInner.moveTopLeft(QPoint(__new.left()+(inner_.left()-outer_.left()),
259 __new.top()+(inner_.top()-outer_.top())));
260 newInner.setSize(QSize(__new.width()-(outer_.width()-inner_.width()),
261 __new.height()-(outer_.height()-inner_.height())));
265 if (hints_.flags & PResizeInc && hints_.width_inc != 0 && hints_.height_inc != 0) {
267 if (hints_.flags & PBaseSize) {
268 base.setWidth(hints_.base_width);
269 base.setHeight(hints_.base_height);
270 } else if (hints_.flags & PMinSize) {
271 base.setWidth(hints_.min_width);
272 base.setHeight(hints_.min_height);
274 QSize newSize(((inner_.width()-base.width())/hints_.width_inc)*hints_.width_inc
276 ((inner_.height()-base.height())/hints_.height_inc)*hints_.height_inc
278 QSize delta(inner_.size() - newSize);
279 QPoint offset(delta.width()/2,delta.height()/2);
280 inner_.setSize(newSize);
281 outer_.setSize(outer_.size() - delta);
282 inner_.moveTopLeft(inner_.topLeft() + offset);
283 outer_.moveTopLeft(outer_.topLeft() + offset);
287 void KWinGrid::applyGeometry()
290 if (orig_.topLeft() == outer_.topLeft())
291 // If the position of the window did not change,
292 // XMoveResizeWindow sometimes still moves the window a little
293 // bit. Seems to have something todo with window gravity
294 // ... we just leave the position allone in that case.
295 XResizeWindow(QX11Info::display(),activeWindow_, inner_.width(),inner_.height());
297 // I don't really know, whats all this stuff concerning window
298 // gravity. I only know, this works for my openoffice windows,
299 // which have StaticGravity. I have not found any window with
300 // a window_gravity of neither StaticGravity nor
301 // NorthWestGravity on my desktop so did not check other
303 QPoint pos = outer_.topLeft();
304 if (hints_.flags & PWinGravity && hints_.win_gravity == StaticGravity)
305 pos = inner_.topLeft();
306 XMoveResizeWindow(QX11Info::display(),activeWindow_,
307 pos.x(),pos.y(), inner_.width(),inner_.height());
313 void KWinGrid::move_TL()
315 move(reserveWest_,reserveNorth_);
318 void KWinGrid::move_TR()
320 move((hsplit_-reserveWest_-reserveEast_)/2+reserveWest_,reserveNorth_);
323 void KWinGrid::move_BL()
325 move(reserveWest_,(vsplit_-reserveNorth_-reserveSouth_)/2+reserveNorth_);
328 void KWinGrid::move_BR()
330 move((hsplit_-reserveWest_-reserveEast_)/2+reserveWest_,
331 (vsplit_-reserveNorth_-reserveSouth_)/2+reserveNorth_);
334 void KWinGrid::resize_Q()
336 resize((hsplit_-reserveWest_-reserveEast_)/2,(vsplit_-reserveNorth_-reserveSouth_)/2);
339 void KWinGrid::resize_H()
341 resize((hsplit_-reserveWest_-reserveEast_),(vsplit_-reserveNorth_-reserveSouth_)/2);
344 void KWinGrid::resize_V()
346 resize((hsplit_-reserveWest_-reserveEast_)/2,vsplit_-reserveNorth_-reserveSouth_);
349 void KWinGrid::resize_F()
351 resize(hsplit_-reserveWest_-reserveEast_,vsplit_-reserveNorth_-reserveSouth_);
354 void KWinGrid::move_L()
359 void KWinGrid::move_R()
364 void KWinGrid::move_U()
369 void KWinGrid::move_D()
374 void KWinGrid::resize_IH()
379 void KWinGrid::resize_DH()
381 resizeRelative(-1,0);
384 void KWinGrid::resize_IV()
389 void KWinGrid::resize_DV()
391 resizeRelative(0,-1);