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__,
15 : split_(split__), ignorestruts_(ignorestruts__), hgap_(hgap__), vgap_(vgap__), hsplit_(hsplit__),
19 connect(KWindowSystem::self(),SIGNAL(activeWindowChanged(WId)),
20 this,SLOT(activeWindowChanged(WId)));
23 void KWinGrid::move(int __xslot, int __yslot)
25 moveResize(__xslot, __yslot, -1, -1);
28 void KWinGrid::resize(int __xsize, int __ysize)
30 moveResize(-1,-1,__xsize,__ysize);
33 void KWinGrid::toDesk(int __desk)
35 int w = activeWindow();
37 KWindowSystem::setOnDesktop(w,__desk);
42 KApplication::kApplication()->quit();
45 int KWinGrid::activeWindow()
47 int av = KWindowSystem::activeWindow();
48 KWindowInfo info = KWindowSystem::windowInfo(av,NET::WMWindowType);
49 if (info.windowType(NET::AllTypesMask) == NET::Desktop) return 0;
53 void KWinGrid::updateTimestamp(void)
55 timestamp_ = QDateTime::currentDateTime();
58 void KWinGrid::activeWindowChanged(WId id)
60 if (!activeWindow_ || timestamp_.isNull())
63 QDateTime tm = QDateTime::currentDateTime();
65 int deltaDays = timestamp_.date().daysTo(tm.date());
66 int deltaMSecs = timestamp_.time().msecsTo(tm.time());
68 if (deltaDays>2 || deltaDays<0) {
73 deltaMSecs += deltaDays * 1000*(60*60*24);
75 if (deltaMSecs <= 300 && deltaMSecs > 0)
76 KWindowSystem::forceActiveWindow(activeWindow_);
81 void KWinGrid::moveResize(int __xslot, int __yslot,
82 int __xsize, int __ysize)
86 QRect newGeometry = doMoveResize(__xslot,__yslot,__xsize,__ysize);
87 updateGeometry(newGeometry);
92 void KWinGrid::moveRelative(int __xdiff, int __ydiff)
96 int xSlot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
97 int ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
101 QPoint p (outer_.topLeft());
102 if (numScreens_ > 1 && p.x() > hsize_) {
104 initGeometry( QApplication::desktop()->screenNumber(p) );
107 } else if (xSlot >= hsplit_) {
108 QPoint p (outer_.topLeft());
109 QRect wa = KWindowSystem::workArea();
110 if (numScreens_ > 1 && p.x() + 2* hsize_ < wa.right()) {
112 initGeometry( QApplication::desktop()->screenNumber(p) );
114 ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_ + __ydiff;
120 else if (ySlot >= vsplit_)
122 QRect newGeometry = doMoveResize(xSlot,ySlot,-1,-1);
123 updateGeometry(newGeometry);
128 void KWinGrid::resizeRelative(int __xdiff, int __ydiff)
132 int xSize = (outer_.width()+hsize_/2)/hsize_;
133 int ySize = (outer_.height()+vsize_/2)/vsize_;
144 QRect newGeometry = doMoveResize(-1,-1,xSize,ySize);
145 updateGeometry(newGeometry);
150 QRect KWinGrid::doMoveResize(int __xslot, int __yslot,
151 int __xsize, int __ysize)
153 QRect newGeometry(outer_);
156 __xsize = (outer_.width()+hsize_/2)/hsize_;
157 if (__xsize<1) __xsize = 1;
158 if (__xsize>hsplit_) __xsize = hsplit_;
161 __ysize = (outer_.height()+vsize_/2)/vsize_;
162 if (__ysize<1) __ysize = 1;
163 if (__ysize>vsplit_) __ysize = vsplit_;
166 newGeometry.setWidth(__xsize*hsize_-hgap_);
167 newGeometry.setHeight(__ysize*vsize_-vgap_);
170 __xslot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
171 if (__xslot<0) __xslot = 0;
172 if (__xslot>=hsplit_) __xslot = hsplit_-1;
175 __yslot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
176 if (__yslot<0) __yslot = 0;
177 if (__yslot>=vsplit_) __yslot = vsplit_-1;
179 newGeometry.moveTopLeft(QPoint(region_.left() + __xslot*hsize_ + hgap_/2,
180 region_.top() + __yslot*vsize_ + vgap_/2));
184 std::ostream& operator<<(std::ostream& os, QRect rect)
186 os << '(' << rect.width() << 'x' << rect.height() << '+' << rect.x() << '+' << rect.y() << ')';
190 std::ostream& operator<<(std::ostream& os, QPoint p)
192 os << '(' << p.x() << ',' << p.y() << ')';
196 std::ostream& operator<<(std::ostream& os, QSize s)
198 os << '(' << s.width() << 'x' << s.height() << ')';
202 void KWinGrid::initGeometry(int __forceScreen)
204 activeWindowChanged(0);
205 if (activeWindow_ == 0)
206 activeWindow_ = activeWindow();
208 KWindowInfo info(KWindowSystem::windowInfo(activeWindow_,NET::WMGeometry|NET::WMFrameExtents));
209 inner_ = info.geometry();
210 outer_ = info.frameGeometry();
213 if (__forceScreen == -1)
214 screen_ = outer_.left()>=split_ ? 1 : 0;
216 screen_ = __forceScreen;
217 region_ = QApplication::desktop()->screenGeometry();
219 region_.setLeft(split_);
221 region_.setRight(split_-1);
224 if (__forceScreen == -1)
225 screen_ = QApplication::desktop()->screenNumber(outer_.topLeft());
227 screen_ = __forceScreen;
228 region_ = QApplication::desktop()->screenGeometry(screen_);
229 numScreens_ = QApplication::desktop()->numScreens();
231 if (screen_ != ignorestruts_) {
232 QRect wa = KWindowSystem::workArea();
233 region_ = region_ & wa;
236 hsize_ = (region_.width()-hgap_)/hsplit_;
237 vsize_ = (region_.height()-vgap_)/vsplit_;
239 int hdelta = region_.width()-hsize_*hsplit_;
240 int vdelta = region_.height()-vsize_*vsplit_;
241 QPoint topLeft(region_.topLeft());
242 topLeft+=QPoint(hdelta/2,vdelta/2);
243 region_.moveTopLeft(topLeft);
244 region_.setSize(QSize(hsize_*hsplit_,vsize_*vsplit_));
247 if (XGetWMNormalHints(QX11Info::display(), activeWindow_, &hints_, &supplied))
248 hints_.flags &= supplied;
254 void KWinGrid::updateGeometry(QRect& __new)
256 QRect newInner(inner_);
257 newInner.moveTopLeft(QPoint(__new.left()+(inner_.left()-outer_.left()),
258 __new.top()+(inner_.top()-outer_.top())));
259 newInner.setSize(QSize(__new.width()-(outer_.width()-inner_.width()),
260 __new.height()-(outer_.height()-inner_.height())));
264 if (hints_.flags & PResizeInc && hints_.width_inc != 0 && hints_.height_inc != 0) {
266 if (hints_.flags & PBaseSize) {
267 base.setWidth(hints_.base_width);
268 base.setHeight(hints_.base_height);
269 } else if (hints_.flags & PMinSize) {
270 base.setWidth(hints_.min_width);
271 base.setHeight(hints_.min_height);
273 QSize newSize(((inner_.width()-base.width())/hints_.width_inc)*hints_.width_inc
275 ((inner_.height()-base.height())/hints_.height_inc)*hints_.height_inc
277 QSize delta(inner_.size() - newSize);
278 QPoint offset(delta.width()/2,delta.height()/2);
279 inner_.setSize(newSize);
280 outer_.setSize(outer_.size() - delta);
281 inner_.moveTopLeft(inner_.topLeft() + offset);
282 outer_.moveTopLeft(outer_.topLeft() + offset);
286 void KWinGrid::applyGeometry()
289 if (orig_.topLeft() == outer_.topLeft())
290 // If the position of the window did not change,
291 // XMoveResizeWindow sometimes still moves the window a little
292 // bit. Seems to have something todo with window gravity
293 // ... we just leave the position allone in that case.
294 XResizeWindow(QX11Info::display(),activeWindow_, inner_.width(),inner_.height());
296 // I don't really know, whats all this stuff concerning window
297 // gravity. I only know, this works for my openoffice windows,
298 // which have StaticGravity. I have not found any window with
299 // a window_gravity of neither StaticGravity nor
300 // NorthWestGravity on my desktop so did not check other
302 QPoint pos = outer_.topLeft();
303 if (hints_.flags & PWinGravity && hints_.win_gravity == StaticGravity)
304 pos = inner_.topLeft();
305 XMoveResizeWindow(QX11Info::display(),activeWindow_,
306 pos.x(),pos.y(), inner_.width(),inner_.height());
312 void KWinGrid::move_TL()
317 void KWinGrid::move_TR()
322 void KWinGrid::move_BL()
327 void KWinGrid::move_BR()
329 move(hsplit_/2,vsplit_/2);
332 void KWinGrid::resize_Q()
334 resize(vsplit_/2,hsplit_/2);
337 void KWinGrid::resize_H()
339 resize(vsplit_,hsplit_/2);
342 void KWinGrid::resize_V()
344 resize(vsplit_/2,hsplit_);
347 void KWinGrid::resize_F()
349 resize(vsplit_,hsplit_);
352 void KWinGrid::move_L()
357 void KWinGrid::move_R()
362 void KWinGrid::move_U()
367 void KWinGrid::move_D()
372 void KWinGrid::resize_IH()
377 void KWinGrid::resize_DH()
379 resizeRelative(-1,0);
382 void KWinGrid::resize_IV()
387 void KWinGrid::resize_DV()
389 resizeRelative(0,-1);