3 #include <kapplication.h>
4 #include <dcopclient.h>
11 #include "kwingrid.moc"
13 KWinGrid::KWinGrid(int hgap__, int vgap__, int hsplit__, int vsplit__, int split__)
14 : DCOPObject("grid"), split_(split__),
15 hgap_(hgap__), vgap_(vgap__), hsplit_(hsplit__), vsplit_(vsplit__)
17 module_ = new KWinModule(KApplication::kApplication());
18 connect(module_,SIGNAL(activeWindowChanged(WId)),this,SLOT(activeWindowChanged(WId)));
21 void KWinGrid::move(int __xslot, int __yslot)
23 moveResize(__xslot, __yslot, -1, -1);
26 void KWinGrid::resize(int __xsize, int __ysize)
28 moveResize(-1,-1,__xsize,__ysize);
31 void KWinGrid::toDesk(int __desk)
33 int w = activeWindow();
35 KWin::setOnDesktop(w,__desk);
40 KApplication::kApplication()->quit();
43 int KWinGrid::activeWindow()
45 int av = module_->activeWindow();
46 KWin::WindowInfo info = KWin::windowInfo(av,NET::WMWindowType);
47 if (info.windowType(NET::AllTypesMask) == NET::Desktop) return 0;
51 void KWinGrid::updateTimestamp(void)
53 timestamp_ = QDateTime::currentDateTime();
56 void KWinGrid::activeWindowChanged(WId id)
58 if (!activeWindow_ || timestamp_.isNull())
61 QDateTime tm = QDateTime::currentDateTime();
63 int deltaDays = timestamp_.date().daysTo(tm.date());
64 int deltaMSecs = timestamp_.time().msecsTo(tm.time());
66 if (deltaDays>2 || deltaDays<0) {
71 deltaMSecs += deltaDays * 1000*(60*60*24);
73 if (deltaMSecs <= 300 && deltaMSecs > 0)
74 KWin::forceActiveWindow(activeWindow_);
79 void KWinGrid::moveResize(int __xslot, int __yslot,
80 int __xsize, int __ysize)
84 QRect newGeometry = doMoveResize(__xslot,__yslot,__xsize,__ysize);
85 updateGeometry(newGeometry);
90 void KWinGrid::moveRelative(int __xdiff, int __ydiff)
94 int xSlot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
95 int ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
99 if (numScreens_ > 1 and screen_ > 0) {
100 initGeometry(screen_-1);
102 ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_ + __ydiff;
105 } else if (xSlot >= hsplit_) {
106 if (numScreens_ > 1 and screen_ < numScreens_-1) {
107 initGeometry(screen_+1);
109 ySlot = (outer_.top()-region_.top()+vsize_/2)/vsize_ + __ydiff;
115 else if (ySlot >= vsplit_)
117 QRect newGeometry = doMoveResize(xSlot,ySlot,-1,-1);
118 updateGeometry(newGeometry);
123 void KWinGrid::resizeRelative(int __xdiff, int __ydiff)
127 int xSize = (outer_.width()+hsize_/2)/hsize_;
128 int ySize = (outer_.height()+vsize_/2)/vsize_;
139 QRect newGeometry = doMoveResize(-1,-1,xSize,ySize);
140 updateGeometry(newGeometry);
145 QRect KWinGrid::doMoveResize(int __xslot, int __yslot,
146 int __xsize, int __ysize)
148 QRect newGeometry(outer_);
151 __xsize = (outer_.width()+hsize_/2)/hsize_;
152 if (__xsize<1) __xsize = 1;
153 if (__xsize>hsplit_) __xsize = hsplit_;
156 __ysize = (outer_.height()+vsize_/2)/vsize_;
157 if (__ysize<1) __ysize = 1;
158 if (__ysize>vsplit_) __ysize = vsplit_;
161 newGeometry.setWidth(__xsize*hsize_-hgap_);
162 newGeometry.setHeight(__ysize*vsize_-vgap_);
165 __xslot = (outer_.left()-region_.left()+hsize_/2)/hsize_;
166 if (__xslot<0) __xslot = 0;
167 if (__xslot>=hsplit_) __xslot = hsplit_-1;
170 __yslot = (outer_.top()-region_.top()+vsize_/2)/vsize_;
171 if (__yslot<0) __yslot = 0;
172 if (__yslot>=vsplit_) __yslot = vsplit_-1;
174 newGeometry.moveTopLeft(QPoint(region_.left() + __xslot*hsize_ + hgap_/2,
175 region_.top() + __yslot*vsize_ + vgap_/2));
179 std::ostream& operator<<(std::ostream& os, QRect rect)
181 os << '(' << rect.width() << 'x' << rect.height() << '+' << rect.x() << '+' << rect.y() << ')';
185 std::ostream& operator<<(std::ostream& os, QPoint p)
187 os << '(' << p.x() << ',' << p.y() << ')';
191 std::ostream& operator<<(std::ostream& os, QSize s)
193 os << '(' << s.width() << 'x' << s.height() << ')';
197 void KWinGrid::initGeometry(int __forceScreen)
199 activeWindowChanged(0);
200 if (activeWindow_ == 0)
201 activeWindow_ = activeWindow();
203 KWin::WindowInfo info(KWin::windowInfo(activeWindow_));
204 inner_ = info.geometry();
205 outer_ = info.frameGeometry();
208 if (__forceScreen == -1)
209 screen_ = outer_.left()>=split_ ? 1 : 0;
211 screen_ = __forceScreen;
212 region_ = QApplication::desktop()->screenGeometry();
214 region_.setLeft(split_);
216 region_.setRight(split_-1);
219 if (__forceScreen == -1)
220 screen_ = QApplication::desktop()->screenNumber(outer_.topLeft());
222 screen_ = __forceScreen;
223 region_ = QApplication::desktop()->screenGeometry(screen_);
224 numScreens_ = QApplication::desktop()->numScreens();
226 QRect wa = module_->workArea();
227 region_ = region_ & wa;
229 hsize_ = (region_.width()-hgap_)/hsplit_;
230 vsize_ = (region_.height()-vgap_)/vsplit_;
232 int hdelta = region_.width()-hsize_*hsplit_;
233 int vdelta = region_.height()-vsize_*vsplit_;
234 QPoint topLeft(region_.topLeft());
235 topLeft+=QPoint(hdelta/2,vdelta/2);
236 region_.moveTopLeft(topLeft);
237 region_.setSize(QSize(hsize_*hsplit_,vsize_*vsplit_));
241 void KWinGrid::updateGeometry(QRect& __new)
243 QRect newInner(inner_);
244 newInner.moveTopLeft(QPoint(__new.left()+(inner_.left()-outer_.left()),
245 __new.top()+(inner_.top()-outer_.top())));
246 newInner.setSize(QSize(__new.width()-(outer_.width()-inner_.width()),
247 __new.height()-(outer_.height()-inner_.height())));
253 if (XGetWMNormalHints(KApplication::kApplication()->getDisplay(),
254 activeWindow_, &hints, &supplied)) {
255 hints.flags &= supplied;
256 if (hints.flags & PResizeInc && hints.width_inc != 0 && hints.height_inc != 0) {
258 if (hints.flags & PBaseSize) {
259 base.setWidth(hints.base_width);
260 base.setHeight(hints.base_height);
261 } else if (hints.flags & PMinSize) {
262 base.setWidth(hints.min_width);
263 base.setHeight(hints.min_height);
265 QSize newSize(((inner_.width()-base.width())/hints.width_inc)*hints.width_inc + base.width(),
266 ((inner_.height()-base.height())/hints.height_inc)*hints.height_inc + base.height());
267 QSize delta(inner_.size() - newSize);
268 QPoint offset(delta.width()/2,delta.height()/2);
269 inner_.setSize(newSize);
270 outer_.setSize(outer_.size() - delta);
271 inner_.moveTopLeft(inner_.topLeft() + offset);
272 outer_.moveTopLeft(outer_.topLeft() + offset);
277 void KWinGrid::applyGeometry()
280 if (orig_.topLeft() == outer_.topLeft())
281 // If the position of the window did not change,
282 // XMoveResizeWindow sometimes still moves the window a little
283 // bit. Seems to have something todo with window gravity
284 // ... we just leave the position allone in that case.
285 XResizeWindow(KApplication::kApplication()->getDisplay(),activeWindow_,
286 inner_.width(),inner_.height());
288 // I don't really know, whats all this stuff concerning window
289 // gravity. I only know, this works for my openoffice windows,
290 // which have StaticGravity. I have not found any window with
291 // a window_gravity of neither StaticGravity nor
292 // NorthWestGravity on my desktop so did not check other
294 QPoint pos = outer_.topLeft();
295 XWindowAttributes winAttributes;
296 if (XGetWindowAttributes(KApplication::kApplication()->getDisplay(),activeWindow_,
297 &winAttributes) && winAttributes.win_gravity == StaticGravity)
298 pos = inner_.topLeft();
299 XMoveResizeWindow(KApplication::kApplication()->getDisplay(),activeWindow_,
300 pos.x(),pos.y(), inner_.width(),inner_.height());
302 //XSync(KApplication::kApplication()->getDisplay(),False);
303 //KWin::forceActiveWindow(activeWindow_);
308 void KWinGrid::move_TL()
313 void KWinGrid::move_TR()
318 void KWinGrid::move_BL()
323 void KWinGrid::move_BR()
325 move(hsplit_/2,vsplit_/2);
329 void KWinGrid::resize_Q()
331 resize(vsplit_/2,hsplit_/2);
334 void KWinGrid::resize_H()
336 resize(vsplit_,hsplit_/2);
339 void KWinGrid::resize_V()
341 resize(vsplit_/2,hsplit_);
344 void KWinGrid::resize_F()
346 resize(vsplit_,hsplit_);
350 void KWinGrid::move_L()
355 void KWinGrid::move_R()
360 void KWinGrid::move_U()
365 void KWinGrid::move_D()
371 void KWinGrid::resize_IH()
376 void KWinGrid::resize_DH()
378 resizeRelative(-1,0);
381 void KWinGrid::resize_IV()
386 void KWinGrid::resize_DV()
388 resizeRelative(0,-1);