1 /* awindow.cc
2 * This file belongs to Worker, a file manager for UN*X/X11.
3 * Copyright (C) 2001-2020 Ralf Hoffmann.
4 * You can contact me at: ralf@boomerangsworld.de
5 * or http://www.boomerangsworld.de/worker
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "awindow.h"
23 #include "text.h"
24 #include "button.h"
25 #include <list>
26 #include <algorithm>
27 #include "utf8.hh"
28
AWindow(AGUIX * aguix,int x,int y,int width,int height,std::string title,wm_window_type_t type)29 AWindow::AWindow( AGUIX *aguix,
30 int x,
31 int y,
32 int width,
33 int height,
34 std::string title,
35 wm_window_type_t type ) : Widget( aguix )
36 {
37 setIsTopLevelWidget( true );
38
39 _x = x;
40 _y = y;
41 _w = ( width > 0 ) ? width : 1;
42 _h = ( height > 0 ) ? height : 1;
43
44 m_open_pos_x = 0;
45 m_open_pos_y = 0;
46 m_open_max_h = false;
47 m_open_max_v = false;
48 m_force_open_position = false;
49
50 _bg = _aguix->getFaces().getColor( "default-bg" );
51
52 if ( _bg < 0 ) {
53 _bg = 0;
54 }
55
56 _title = title;
57 onScreen=false;
58 border = 5;
59 win = 0;
60 doTabCycling = false;
61 forbidinput = 0;
62 #ifdef USE_XIM
63 inputcontext = NULL;
64 #endif
65 req = NULL;
66 mapNr = 0;
67 container = NULL;
68 contAutoResize = false;
69 msgW = msgH = -1;
70
71 _callback_forbidden = false;
72
73 m_window_type = type;
74
75 m_size_hints = NULL;
76 }
77
getAGUIX() const78 AGUIX *AWindow::getAGUIX() const
79 {
80 return _aguix;
81 }
82
sizeChanged(int width,int height,bool explicit_resize)83 void AWindow::sizeChanged(int width,int height, bool explicit_resize)
84 {
85 if ( width != _w || height != _h ) {
86 AGMessage *agmsg = AGUIX_allocAGMessage();
87 agmsg->type=AG_SIZECHANGED;
88 agmsg->size.window=win;
89 agmsg->size.neww=width;
90 agmsg->size.newh=height;
91 agmsg->size.explicit_resize = explicit_resize;
92 _aguix->putAGMsg(agmsg);
93 _w = width;
94 _h = height;
95 if ( ( container != NULL ) && ( contAutoResize == true ) ) {
96 container->resize( _w, _h );
97 container->rearrange();
98 }
99 }
100 }
101
redraw()102 void AWindow::redraw()
103 {
104 if ( _created == true ) {
105 for ( childs_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
106 (*it1)->redraw();
107 }
108 }
109 }
110
getWindow() const111 Window AWindow::getWindow() const
112 {
113 return win;
114 }
115
~AWindow()116 AWindow::~AWindow()
117 {
118 if ( container != NULL ) {
119 delete container;
120 container = NULL;
121 }
122 while ( _childs.size() ) {
123 delete *( _childs.begin() );
124 }
125 if ( req != NULL ) {
126 delete req;
127 req = NULL;
128 }
129 destroy();
130 }
131
getBG() const132 int AWindow::getBG() const
133 {
134 return _bg;
135 }
136
setBG(int tbg)137 void AWindow::setBG(int tbg)
138 {
139 _bg = tbg;
140 }
141
ReactMessage(Message * msg)142 void AWindow::ReactMessage(Message *msg)
143 {
144 if((msg->window)!=win) return;
145 // diese Message interressiert uns
146 }
147
setMaxSize(int mwidth,int mheight)148 void AWindow::setMaxSize(int mwidth,int mheight)
149 {
150 Display *dsp = _aguix->getDisplay();
151
152 if ( ! m_size_hints ) {
153 m_size_hints = XAllocSizeHints();
154 }
155
156 if ( m_size_hints ) {
157 if ( minw >= 0 ) {
158 m_size_hints->flags |= PMaxSize | PMinSize;
159 m_size_hints->min_width = minw;
160 m_size_hints->min_height = minh;
161 } else {
162 m_size_hints->flags |= PMaxSize;
163 }
164 m_size_hints->max_width = mwidth;
165 m_size_hints->max_height = mheight;
166
167 XSetWMNormalHints( dsp, win, m_size_hints );
168 }
169
170 maxw = mwidth;
171 maxh = mheight;
172 }
173
setMinSize(int mwidth,int mheight)174 void AWindow::setMinSize(int mwidth,int mheight)
175 {
176 Display *dsp = _aguix->getDisplay();
177
178 if ( ! m_size_hints ) {
179 m_size_hints = XAllocSizeHints();
180 }
181
182 if ( m_size_hints ) {
183 if ( maxw >= 0 ) {
184 m_size_hints->flags |= PMaxSize | PMinSize;
185 m_size_hints->max_width = maxw;
186 m_size_hints->max_height = maxh;
187 } else {
188 m_size_hints->flags |= PMinSize;
189 }
190 m_size_hints->min_width = mwidth;
191 m_size_hints->min_height = mheight;
192
193 XSetWMNormalHints( dsp, win, m_size_hints );
194 }
195
196 minw = mwidth;
197 minh = mheight;
198 }
199
show()200 void AWindow::show()
201 {
202 if(onScreen==true) return;
203 Display *dsp=_aguix->getDisplay();
204
205 XMapWindow(dsp,win);
206
207 if ( m_force_open_position &&
208 ( m_open_max_h || m_open_max_v ) ) {
209 // see
210 // https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm140130317598336
211 XEvent ev;
212
213 memset( &ev, 0, sizeof( ev ) );
214 ev.type = ClientMessage;
215 ev.xclient.window = win;
216 ev.xclient.message_type = _aguix->getAtom( AGUIX::NET_WM_STATE );
217 ev.xclient.format = 32;
218 ev.xclient.data.l[0] = 1;
219
220 if ( m_open_max_h && m_open_max_v ) {
221 ev.xclient.data.l[1] = _aguix->getAtom( AGUIX::NET_WM_STATE_MAXIMIZED_HORZ );
222 ev.xclient.data.l[2] = _aguix->getAtom( AGUIX::NET_WM_STATE_MAXIMIZED_VERT );
223 } else if ( m_open_max_h ) {
224 ev.xclient.data.l[1] = _aguix->getAtom( AGUIX::NET_WM_STATE_MAXIMIZED_HORZ );
225 ev.xclient.data.l[2] = 0;
226 } else {
227 ev.xclient.data.l[1] = _aguix->getAtom( AGUIX::NET_WM_STATE_MAXIMIZED_VERT );
228 ev.xclient.data.l[2] = 0;
229 }
230
231 ev.xclient.data.l[3] = 1;
232 XSendEvent( dsp, DefaultRootWindow( _aguix->getDisplay() ),
233 False, SubstructureRedirectMask,
234 &ev);
235 }
236
237 onScreen=true;
238 _aguix->xSync();
239 }
240
hide()241 void AWindow::hide()
242 {
243 if(onScreen==false) return;
244 Display *dsp=_aguix->getDisplay();
245 XUnmapWindow(dsp,win);
246 onScreen=false;
247 }
248
hide(Window subwin)249 void AWindow::hide(Window subwin)
250 {
251 if(hasSubWin(subwin)==true) {
252 Display *dsp=_aguix->getDisplay();
253 XUnmapWindow(dsp,subwin);
254 }
255 }
256
show(Window subwin)257 void AWindow::show(Window subwin)
258 {
259 if(hasSubWin(subwin)==true) {
260 Display *dsp=_aguix->getDisplay();
261 XMapWindow(dsp,subwin);
262 }
263 }
264
getTitle() const265 const char *AWindow::getTitle() const
266 {
267 return _title.c_str();
268 }
269
setTitle(std::string newtitle)270 void AWindow::setTitle( std::string newtitle)
271 {
272 _title = newtitle;
273 setWMTitle();
274 }
275
resizeSubWin(Window twin,int tw,int th)276 void AWindow::resizeSubWin(Window twin,int tw,int th)
277 {
278 Display *dsp=_aguix->getDisplay();
279
280 if ( tw < 1 ) tw = 1;
281 if ( th < 1 ) th = 1;
282
283 XResizeWindow(dsp,twin,tw,th);
284 }
285
moveSubWin(Window twin,int tx,int ty)286 void AWindow::moveSubWin(Window twin,int tx,int ty)
287 {
288 Display *dsp=_aguix->getDisplay();
289 XMoveWindow(dsp,twin,tx,ty);
290 }
291
handleMessage(XEvent * E,Message * msg)292 bool AWindow::handleMessage(XEvent *E,Message *msg)
293 {
294 bool returnvalue=false;
295 int res;
296 bool conLock;
297 GUIElement *guielem;
298
299 // continue when we own lockElement
300 conLock = false;
301 if ( msg->lockElement != NULL ) {
302 if ( contains( msg->lockElement ) == true ) conLock = true;
303 }
304
305 //check for some input unrelated events
306 if ( ( ( msg->type == MapNotify ) &&
307 ( msg->window == win ) ) ||
308 ( ( msg->type == UnmapNotify ) &&
309 ( msg->window == win ) ) ) {
310 mapNr++;
311 }
312
313 // return if we don't handle messages
314 if ( ( getForbidInput() == true ) &&
315 ( msg->type != Expose ) &&
316 ( msg->type != ConfigureNotify ) &&
317 ( msg->type != FocusIn ) &&
318 ( msg->type != FocusOut ) ) {
319 // but only without lockElement or we don't own it
320 if ( conLock == false ) return returnvalue;
321 }
322
323 if ( msg->loop == 0 ) {
324 // the following code has to be executed no matter
325 // in which state the gui is so does it always but only the first loop
326 switch ( msg->type ) {
327 case FocusIn:
328 #ifdef USE_XIM
329 if ( inputcontext != NULL ) {
330 if ( msg->window == win ) {
331 XSetICFocus( inputcontext );
332 }
333 }
334 #endif
335 if ( ( getForbidInput() == true ) && ( conLock == false ) ) return returnvalue;
336 break;
337 case FocusOut:
338 #ifdef USE_XIM
339 if ( inputcontext != NULL ) {
340 if ( msg->window == win ) {
341 XUnsetICFocus( inputcontext );
342 }
343 }
344 #endif
345 if ( ( getForbidInput() == true ) && ( conLock == false ) ) return returnvalue;
346 break;
347 }
348
349 if(msg->window==win) {
350 if(msg->type==ConfigureNotify) {
351 if ( ( msg->width != msgW ) || ( msg->height != msgH ) ) {
352 msgW = msg->width;
353 msgH = msg->height;
354 sizeChanged( msg->width, msg->height, false );
355 }
356 }
357 }
358 }
359
360 if ( msg->type == ConfigureNotify ) {
361 if ( getForbidInput() == true && conLock == false ) return returnvalue;
362 }
363
364 // Alle Element bekommen Nachricht
365 res = 0;
366 for ( childs_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
367 //TODO Original wurden nur den GUIElement eine msg geschickt,
368 // man koennte aber auch den AWindows die Msg weitergeben
369 // und in AGUIX nur noch Toplevel anstossen
370 // Es koennte aber Probleme machen, wenn ich bei
371 // res == 1 abbreche
372 guielem = dynamic_cast<GUIElement*>( (*it1) );
373 if ( guielem != NULL ) {
374 res = guielem->handleMessageLock( E, msg );
375 if ( ( res == 1 ) && ( conLock == false ) ) {
376 returnvalue = true;
377 break;
378 }
379 }
380 }
381
382 if ( msg->lockElement == NULL ) {
383 if ( doTabCycling == true ) {
384 if ( isParent( msg->window, false ) == true ) {
385 if ( msg->type == KeyPress ) {
386 int keystate = KEYSTATEMASK( msg->keystate );
387 if ( ( msg->key == XK_Tab ) && ( keystate == 0 ) ) {
388 nextFocus();
389 } else if ( ( ( msg->key == XK_ISO_Left_Tab ) ||
390 ( msg->key == XK_Tab ) ) && ( keystate == ShiftMask ) ) {
391 // my system sends ISO_Left_Tab when tab is pressed together with ShiftMask
392 // so I allow normal tab key and this variant
393 prevFocus();
394 }
395 }
396 }
397 }
398 }
399
400 if ( msg->lockElement == NULL &&
401 msg->type == KeyPress &&
402 isTopLevel() == true &&
403 callBackForbidden() == false ) {
404 std::list<key_listener_t>::iterator it;
405 AGMessage *agmsg = AGUIX_allocAGMessage( msg );
406
407 for ( it = key_listener.begin(); it != key_listener.end(); it++ ) {
408 //TODO pruefen, ob subwin ue1berhautp ein subwin von this is, also recursiv alle childs pruefen
409 if ( ( (*it).mode & KEYCB_WHENVISIBLE ) == 0 || (*it).subwin->isVisible() == true ) {
410 forbidCallBacks();
411 (*it).cb->run( (*it).subwin, *agmsg );
412 permitCallBacks();
413 }
414 }
415 AGUIX_freeAGMessage( agmsg );
416 }
417
418 return returnvalue;
419 }
420
hasSubWin(Window twin) const421 bool AWindow::hasSubWin(Window twin) const
422 {
423 std::list<Window>::const_iterator it1;
424
425 it1 = std::find( subwins.begin(), subwins.end(), twin );
426 if ( it1 == subwins.end() ) return false;
427 return true;
428 }
429
getSubWindow(Window parent,int tx,int ty,int tw,int th)430 Window AWindow::getSubWindow(Window parent,int tx,int ty,int tw,int th)
431 {
432 Window newwin,pwin;
433 Display *dsp=_aguix->getDisplay();
434 int scr=_aguix->getScreen();
435 Visual *vis=DefaultVisual(dsp,scr);
436 unsigned long mask=CWEventMask|CWBackPixel|CWColormap;
437
438 if ( tw < 1 ) tw = 1;
439 if ( th < 1 ) th = 1;
440
441 XSetWindowAttributes attr;
442 attr.event_mask=ExposureMask|ButtonPressMask|ButtonReleaseMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask|ButtonMotionMask|EnterWindowMask|LeaveWindowMask|PointerMotionHintMask;
443 attr.background_pixel=_aguix->getPixel(_bg);
444 attr.colormap=_aguix->getColormap();
445
446 if ( ( parent != 0 ) && ( hasSubWin( parent ) == true ) )
447 pwin = parent;
448 else
449 pwin = win;
450
451 newwin=XCreateWindow(dsp,pwin,tx,ty,tw,th,0,_aguix->getDepth(),InputOutput,vis,mask,&attr);
452 if(!newwin) {
453 return newwin;
454 }
455 XMapRaised(dsp,newwin);
456 XClearWindow(dsp,newwin);
457 subwins.push_back( newwin );
458 return newwin;
459 }
460
removeSubWin(Window subwin)461 void AWindow::removeSubWin(Window subwin)
462 {
463 if(hasSubWin(subwin)==true) {
464 Display *dsp=_aguix->getDisplay();
465 XDestroyWindow(dsp,subwin);
466 subwins.remove( subwin );
467 }
468 }
469
isParent(Window childwin,bool direct) const470 bool AWindow::isParent(Window childwin,bool direct) const
471 {
472 bool found = false;
473 AWindow *twin;
474
475 if ( direct == false ) {
476 for ( childs_const_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
477 twin = dynamic_cast<AWindow*>( (*it1) );
478 if ( twin != NULL ) {
479 if ( twin->isParent( childwin, false ) == true ) {
480 found = true;
481 break;
482 }
483 }
484 }
485 }
486 if ( found == false && hasSubWin( childwin ) == true ) found = true;
487 if ( childwin == win ) found = true;
488 return found;
489 }
490
isParent(Window childwin) const491 bool AWindow::isParent( Window childwin ) const
492 {
493 return isParent( childwin, true );
494 }
495
move(int nx,int ny)496 void AWindow::move(int nx,int ny)
497 {
498 Display *dsp=_aguix->getDisplay();
499 XMoveWindow(dsp,win,nx,ny);
500 _x = nx;
501 _y = ny;
502 }
503
resize(int nw,int nh)504 void AWindow::resize(int nw,int nh)
505 {
506 int newminw, newminh, newmaxw, newmaxh;
507
508 if ( ( nw > 0 ) && ( nh > 0 ) ) {
509 if ( ( nw != _w ) || ( nh != _h ) ) {
510 Display *dsp=_aguix->getDisplay();
511
512 // first check if we doesn't crash with the min/maxwidths
513 // some WMs doesn't allow resize in this case (atleast KWM)
514 if ( minw > 0 ) {
515 newminw = ( nw < minw ) ? nw : minw;
516 newminh = ( nh < minh ) ? nh : minh;
517 if ( ( newminw != minw ) || ( newminh != minh ) ) {
518 setMinSize( newminw, newminh );
519 }
520 }
521 if ( maxw > 0 ) {
522 newmaxw = ( nw > maxw ) ? nw : maxw;
523 newmaxh = ( nh > maxh ) ? nh : maxh;
524 if ( ( newmaxw != maxw ) || ( newmaxh != maxh ) ) {
525 setMaxSize( newmaxw, newmaxh );
526 }
527 }
528
529 XResizeWindow(dsp,win,nw,nh);
530 #if 0
531 // it's possible to not call sizeChanged here
532 // but the size has to be stored so if one use
533 // this case, the test in sizeChanged for different size
534 // has to be removed because it would be always true in the
535 // manual resize case
536 _w = nw;
537 _h = nh;
538 #else
539 sizeChanged( nw, nh, true );
540 #endif
541 }
542 }
543 }
544
findWidgetForWindow(Window child)545 Widget *AWindow::findWidgetForWindow( Window child )
546 {
547 childs_const_it it1;
548
549 for ( it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
550 if ( (*it1)->isParent( child ) == true ) break;
551 }
552 if ( it1 == _childs.end() ) return NULL;
553 return *it1;
554 }
555
setCursor(int type)556 void AWindow::setCursor(int type)
557 {
558 _aguix->setCursor(win,type);
559 }
560
unsetCursor()561 void AWindow::unsetCursor()
562 {
563 _aguix->unsetCursor(win);
564 }
565
invalidFocus()566 void AWindow::invalidFocus()
567 {
568 Focus *f;
569 Widget *w;
570
571 // we could had a focus owner before getting a parent awindow
572 // so first check if we have not one
573 if(_parent!=NULL) {
574 _parent->invalidFocus();
575 }
576 // if we have a focus owner, release it
577 f = getFocusElement( this );
578 if ( f != NULL ) {
579 setFocusElement( this, NULL );
580 w = dynamic_cast<Widget*>( f );
581 if ( w != NULL )
582 w->redraw();
583 }
584 }
585
applyFocus(Widget * newfocus)586 void AWindow::applyFocus( Widget *newfocus )
587 {
588 if ( ( newfocus != NULL ) && ( isOwner( newfocus ) == true ) ) return;
589
590 invalidFocus();
591 if ( newfocus != NULL ) {
592 if ( _parent != NULL ) {
593 _parent->applyFocus( newfocus );
594 } else {
595 setFocusElement( this, newfocus );
596 newfocus->redraw();
597 }
598 }
599 }
600
isOwner(Widget * f) const601 bool AWindow::isOwner( Widget *f ) const
602 {
603 if(_parent!=NULL) {
604 return _parent->isOwner(f);
605 } else {
606 if ( getFocusElement( this ) == f ) return true;
607 }
608 return false;
609 }
610
maximizeX()611 void AWindow::maximizeX()
612 {
613 int mw,tw;
614
615 mw = 0;
616
617 for ( childs_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
618 tw = (*it1)->getX() + (*it1)->getWidth() + border;
619 if ( tw > mw )
620 mw = tw;
621 }
622 if ( mw > _w ) {
623 resize( mw, _h );
624 }
625 }
626
maximizeY()627 void AWindow::maximizeY()
628 {
629 int mh,th;
630
631 mh = 0;
632 for ( childs_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
633 th = (*it1)->getY() + (*it1)->getHeight() + border;
634 if ( th > mh )
635 mh = th;
636 }
637 if ( mh > _h ) {
638 resize( _w, mh );
639 }
640 }
641
getBorderWidth() const642 int AWindow::getBorderWidth() const
643 {
644 return border;
645 }
646
setBorderWidth(int nv)647 void AWindow::setBorderWidth( int nv )
648 {
649 if ( ( nv < 0 ) ||
650 ( nv >= _w/2 ) ) return;
651 border = nv;
652 }
653
addTextFromString(const char * text,int tx,int ty,int vspace,Text *** return_texts,int * return_count,int * return_y)654 int AWindow::addTextFromString( const char *text,
655 int tx,
656 int ty,
657 int vspace,
658 Text ***return_texts,
659 int *return_count,
660 int *return_y )
661 {
662 int i;
663 int lines;
664 char **liness;
665 Text **text_elems;
666
667 if ( text == NULL ) return 1;
668
669 if ( tx < 0 ) tx = 0;
670 if ( ty < 0 ) ty = 0;
671 if ( vspace < 0 ) vspace = 0;
672
673 lines = createLines( text, &liness );
674
675 text_elems = (Text**)_allocsafe( sizeof( Text* ) * lines );
676
677 for ( i = 0; i < lines; i++ ) {
678 text_elems[i] = (Text*)add( new Text( _aguix, tx, ty, liness[i] ) );
679 ty += text_elems[i]->getHeight() + vspace;
680 }
681
682 if ( return_texts != NULL ) {
683 // caller want the Text list
684 *return_texts = text_elems;
685 } else _freesafe( text_elems );
686
687 if ( return_count != NULL ) {
688 *return_count = lines;
689 }
690
691 if ( return_y != NULL ) {
692 // ty is not the real y value because vspace is always added
693 *return_y = ty - vspace;
694 }
695
696 for ( i = 0; i < lines; i++ ) _freesafe( liness[i] );
697 _freesafe( liness );
698
699 return 0;
700 }
701
addMultiLineText(const std::string text,AContainer & ac,int xpos,int ypos,AContainer ** return_container,std::list<Text * > * return_text_list,bool split_on_newline)702 int AWindow::addMultiLineText( const std::string text,
703 AContainer &ac,
704 int xpos, int ypos,
705 AContainer **return_container,
706 std::list<Text*> *return_text_list,
707 bool split_on_newline )
708 {
709 int i;
710 int lines;
711 char **liness;
712 Text *textelement;
713
714 if ( split_on_newline ) {
715 lines = createLines( text.c_str(), &liness, '\n' );
716 } else {
717 lines = createLines( text.c_str(), &liness );
718 }
719
720 AContainer *textac = ac.add( new AContainer( this, 1, lines ), xpos, ypos );
721 textac->setMinSpace( 5 );
722 textac->setMaxSpace( 5 );
723 textac->setBorderWidth( 0 );
724
725 for ( i = 0; i < lines; i++ ) {
726 textelement = (Text*)textac->add( new Text( _aguix, 0, 0, liness[i] ),
727 0, i, AContainer::CO_INCWNR );
728 if ( return_text_list != NULL ) {
729 return_text_list->push_back( textelement );
730 }
731 }
732
733 for ( i = 0; i < lines; i++ ) _freesafe( liness[i] );
734 _freesafe( liness );
735
736 if ( return_container != NULL ) *return_container = textac;
737 return 0;
738 }
739
centerScreen()740 void AWindow::centerScreen()
741 {
742 int rw, rh, nx, ny;
743
744 _aguix->getLargestDimensionOfCurrentScreen( NULL, NULL, &rw, &rh );
745
746 if ( ( rw < 1 ) || ( rh < 1 ) ) return;
747
748 nx = ( rw / 2 ) - ( _w / 2 );
749 ny = ( rh / 2 ) - ( _h / 2 );
750 move( nx, ny );
751 }
752
contains(Widget * elem) const753 bool AWindow::contains( Widget *elem ) const
754 {
755 bool returnvalue = false;
756 AWindow *twin;
757
758 for ( childs_const_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
759 if ( (*it1) == elem ) {
760 returnvalue = true;
761 break;
762 }
763 }
764 if ( returnvalue == false ) {
765 for ( childs_const_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
766 twin = dynamic_cast<AWindow*>( (*it1) );
767 if ( twin != NULL ) {
768 if ( twin->contains( elem ) == true ) {
769 returnvalue = true;
770 break;
771 }
772 }
773 }
774 }
775 return returnvalue;
776 }
777
getFocusOwner() const778 Widget *AWindow::getFocusOwner() const
779 {
780 Focus *f;
781
782 if ( _parent != NULL )
783 return _parent->getFocusOwner();
784 f = getFocusElement( this );
785 if ( f == NULL ) return NULL;
786 return dynamic_cast<Widget*>( f );
787 }
788
nextFocus()789 void AWindow::nextFocus()
790 {
791 Widget *tw, *next;
792 Focus *f;
793
794 if ( _parent != NULL ) {
795 _parent->nextFocus();
796 } else {
797
798 f = getFocusElement( this );
799 tw = dynamic_cast<Widget*>( f );
800 next = searchNextFocus( tw );
801
802 if ( next != NULL ) {
803 applyFocus( next );
804 }
805 }
806 }
807
prevFocus()808 void AWindow::prevFocus()
809 {
810 Widget *tw, *prev;
811 Focus *f;
812
813 if ( _parent != NULL ) {
814 _parent->prevFocus();
815 } else {
816
817 f = getFocusElement( this );
818 tw = dynamic_cast<Widget*>( f );
819 prev = searchPrevFocus( tw );
820
821 if ( prev != NULL ) {
822 applyFocus( prev );
823 }
824 }
825 }
826
setDoTabCycling(bool nv)827 void AWindow::setDoTabCycling( bool nv )
828 {
829 doTabCycling = nv;
830 }
831
getDoTabCycling() const832 bool AWindow::getDoTabCycling() const
833 {
834 return doTabCycling;
835 }
836
isTopParent(Window childwin)837 bool AWindow::isTopParent( Window childwin )
838 {
839 if ( _parent != NULL )
840 return _parent->isTopParent( childwin );
841 else
842 return isParent( childwin, false );
843 }
844
isVisible() const845 bool AWindow::isVisible() const
846 {
847 if ( onScreen == false ) return false;
848 else {
849 if ( _parent != NULL ) {
850 if ( _parent->isVisible() == true ) return true;
851 else return false;
852 } else {
853 return true;
854 }
855 }
856 }
857
useStippleBackground()858 void AWindow::useStippleBackground()
859 {
860 _aguix->setWindowBackgroundPixmap( win );
861 }
862
forbidUserInput()863 void AWindow::forbidUserInput()
864 {
865 forbidinput++;
866 }
867
permitUserInput()868 void AWindow::permitUserInput()
869 {
870 forbidinput--;
871 if ( forbidinput < 0 ) forbidinput = 0;
872 }
873
getForbidInput() const874 bool AWindow::getForbidInput() const
875 {
876 if ( _parent != NULL )
877 return _parent->getForbidInput();
878 else
879 return ( forbidinput == 0 ) ? false : true;
880 }
881
setTransientForAWindow(const AWindow * twin)882 void AWindow::setTransientForAWindow( const AWindow *twin )
883 {
884 if ( win == 0 ) return;
885 if ( twin == NULL ) {
886 XSetTransientForHint( _aguix->getDisplay(), getWindow(), None );
887 } else {
888 XSetTransientForHint( _aguix->getDisplay(), getWindow(), twin->getWindow() );
889 }
890 }
891
892 #ifdef USE_XIM
getXIC() const893 XIC AWindow::getXIC() const
894 {
895 return inputcontext;
896 }
897
createXIC()898 int AWindow::createXIC()
899 {
900 long im_event_mask;
901 XWindowAttributes attr;
902
903 if ( _parent != NULL ) {
904 inputcontext = NULL;
905 return 0;
906 }
907
908 if ( ( _aguix->getXIM() != NULL ) && ( _aguix->getXIMStyle() != 0 ) ) {
909 _aguix->Flush();
910 inputcontext = XCreateIC( _aguix->getXIM(),
911 XNInputStyle, _aguix->getXIMStyle(),
912 XNClientWindow, win,
913 (void*)NULL );
914 if ( inputcontext == NULL ) {
915 fprintf( stderr, "Worker Warning: Cannot create input context\n");
916 } else {
917 XGetICValues( inputcontext, XNFilterEvents, &im_event_mask, (void*)NULL );
918 XGetWindowAttributes( _aguix->getDisplay(), win, &attr );
919 XSelectInput( _aguix->getDisplay(), win, attr.your_event_mask | im_event_mask );
920 }
921 } else {
922 inputcontext = NULL;
923 }
924 return ( ( inputcontext != NULL ) ? 0 : 1 );
925 }
926
closeXIC()927 void AWindow::closeXIC()
928 {
929 if ( inputcontext != NULL ) {
930 XDestroyIC( inputcontext );
931 inputcontext = NULL;
932 }
933 }
934
XICdestroyed()935 void AWindow::XICdestroyed()
936 {
937 inputcontext = NULL;
938 }
939
940 #endif
941
isTopLevel() const942 bool AWindow::isTopLevel() const
943 {
944 return ( ( _parent == NULL ) ? true : false );
945 }
946
request(const char * reqtitle,const char * text,const char * buttons,Requester::request_flags_t flags)947 int AWindow::request( const char *reqtitle, const char *text, const char *buttons, Requester::request_flags_t flags )
948 {
949 if ( _parent != NULL ) {
950 return _parent->request( reqtitle, text, buttons, flags );
951 }
952
953 if ( req == NULL ) {
954 req = new Requester( _aguix, this );
955 }
956 return req->request( reqtitle, text, buttons, flags );
957 }
958
string_request(const char * reqtitle,const char * lines,const char * default_str,const char * buttons,char ** return_str,Requester::request_flags_t flags)959 int AWindow::string_request( const char *reqtitle, const char *lines, const char *default_str, const char *buttons, char **return_str, Requester::request_flags_t flags )
960 {
961 if ( _parent != NULL ) {
962 return _parent->string_request( reqtitle, lines, default_str, buttons, return_str, flags );
963 }
964
965 if ( req == NULL ) {
966 req = new Requester( _aguix, this );
967 }
968 return req->string_request( reqtitle, lines, default_str, buttons, return_str, flags );
969 }
970
getMapNr() const971 int AWindow::getMapNr() const
972 {
973 return mapNr;
974 }
975
setContainer(AContainer * newcont,bool autoResize)976 AContainer *AWindow::setContainer( AContainer *newcont, bool autoResize )
977 {
978 container = newcont;
979 contAutoResize = autoResize;
980 return newcont;
981 }
982
removeContainer(AContainer * cont)983 void AWindow::removeContainer( AContainer *cont )
984 {
985 if ( container == cont ) {
986 container = NULL;
987 }
988 }
989
removeFromContainer(Widget * twid)990 void AWindow::removeFromContainer( Widget *twid )
991 {
992 if ( container != NULL ) {
993 container->remove( twid );
994 }
995 }
996
contMaximize(bool applyMinSize,bool applyMaxSize)997 void AWindow::contMaximize( bool applyMinSize, bool applyMaxSize )
998 {
999 int tw, th;
1000
1001 if ( container != NULL ) {
1002 // to maximize the window get the min width/height for
1003 // the container by resizing to 0,0 and finally add position
1004 container->resize( 0, 0 );
1005 container->rearrange();
1006 tw = container->getWidth();
1007 th = container->getHeight();
1008 tw += container->getX();
1009 th += container->getY();
1010 if ( applyMinSize == true ) setMinSize( tw, th );
1011 if ( applyMaxSize == true ) setMaxSize( tw, th );
1012 resize( tw, th );
1013 }
1014 }
1015
doCreateStuff()1016 void AWindow::doCreateStuff()
1017 {
1018 Display *dsp = _aguix->getDisplay();
1019 Window ParentWnd;
1020 int scr;
1021 Visual *vis;
1022 unsigned long mask = CWEventMask | CWBackPixel | CWColormap;
1023 XSetWindowAttributes attr;
1024 XWMHints *WMHints;
1025
1026 scr = _aguix->getScreen();
1027 vis = DefaultVisual( dsp, scr );
1028
1029 if ( _parent == NULL ) {
1030 ParentWnd = RootWindow( dsp, scr );
1031 } else {
1032 ParentWnd = _parent->win;
1033 }
1034
1035 attr.event_mask =
1036 ExposureMask |
1037 ButtonPressMask |
1038 ButtonReleaseMask |
1039 StructureNotifyMask |
1040 KeyPressMask |
1041 KeyReleaseMask |
1042 ButtonMotionMask |
1043 PointerMotionHintMask |
1044 FocusChangeMask;
1045 attr.background_pixel = _aguix->getPixel( _bg );
1046 attr.colormap = _aguix->getColormap();
1047
1048 // create window
1049 win = XCreateWindow( dsp, ParentWnd,
1050 m_force_open_position ? m_open_pos_x : _x,
1051 m_force_open_position ? m_open_pos_y : _y,
1052 _w, _h, 0, _aguix->getDepth(), InputOutput, vis, mask, &attr );
1053 if ( !win ) {
1054 return;
1055 }
1056
1057 maxw = -1;
1058 maxh = -1;
1059 minw = -1;
1060 minh = -1;
1061
1062 // now set advanced window attributes (for window managers...)
1063 setWMTitle();
1064
1065 // for close button
1066 XSetWMProtocols( dsp, win, _aguix->getCloseAtom(), 1 );
1067
1068 // size of the window
1069 if ( ! m_size_hints ) {
1070 m_size_hints = XAllocSizeHints();
1071 }
1072
1073 if ( m_size_hints ) {
1074 m_size_hints->flags = PSize;
1075 m_size_hints->width = _w;
1076 m_size_hints->height = _h;
1077
1078 if ( m_force_open_position ) {
1079 m_size_hints->flags |= USPosition;
1080
1081 m_size_hints->x = m_open_pos_x;
1082 m_size_hints->y = m_open_pos_y;
1083 }
1084
1085 XSetWMNormalHints( dsp, win, m_size_hints );
1086 }
1087
1088 // window grouping for window managers
1089 WMHints = XAllocWMHints();
1090 if ( WMHints ) {
1091 WMHints->input = True;
1092 WMHints->window_group = _aguix->getGroupWin();
1093 WMHints->flags = InputHint | WindowGroupHint;
1094 XSetWMHints( dsp, win, WMHints );
1095 XFree( WMHints );
1096 }
1097
1098 // command so the window manager can restart worker
1099 XSetCommand( dsp, win, _aguix->getargv(), _aguix->getargc() );
1100
1101 if ( _aguix->getApplyWindowDialogType() ) {
1102 Atom window_type_atom;
1103
1104 if ( m_window_type == AWINDOW_DIALOG ) {
1105 window_type_atom = _aguix->getAtom( AGUIX::NET_WM_WINDOW_TYPE_DIALOG );
1106 } else {
1107 window_type_atom = _aguix->getAtom( AGUIX::NET_WM_WINDOW_TYPE_NORMAL );
1108 }
1109
1110 XChangeProperty( dsp, win,
1111 _aguix->getAtom( AGUIX::NET_WM_WINDOW_TYPE ),
1112 XA_ATOM, 32, PropModeReplace, (unsigned char *) &window_type_atom, 1 );
1113 }
1114
1115 if ( m_window_type == AWINDOW_DIALOG ) {
1116 const AWindow *twin = _aguix->getTransientWindow();
1117
1118 if ( twin ) {
1119 setTransientForAWindow( twin );
1120 }
1121 }
1122
1123 applyIcon();
1124
1125 // clear window
1126 XClearWindow( dsp, win );
1127
1128 // insert window into _aguix
1129 if ( m_window_type == AWINDOW_DIALOG ) {
1130 _aguix->insertWindow( this, false );
1131 } else {
1132 _aguix->insertWindow( this, true );
1133 }
1134
1135 #ifdef USE_XIM
1136 // create xinput stuff
1137 createXIC();
1138 #endif
1139 Widget::doCreateStuff();
1140
1141 _aguix->Flush();
1142 return;
1143 }
1144
doDestroyStuff()1145 void AWindow::doDestroyStuff()
1146 {
1147 if ( _created == true ) {
1148 Display *dsp=_aguix->getDisplay();
1149 _aguix->removeWindow( this );
1150
1151 #ifdef WMDESTROYBUGFIX
1152 if ( _parent == NULL ) {
1153 _aguix->Flush();
1154 XSync( dsp, False );
1155 waittime( 10 );
1156 }
1157 #endif
1158 #ifdef USE_XIM
1159 closeXIC();
1160 #endif
1161 if ( win != 0 ) {
1162 XDestroyWindow( dsp, win );
1163 win = 0;
1164 }
1165 _aguix->Flush();
1166
1167 if ( m_size_hints ) {
1168 XFree( m_size_hints );
1169 m_size_hints = NULL;
1170 }
1171 }
1172
1173 onScreen = false;
1174 _title = "";
1175 Widget::doDestroyStuff();
1176 }
1177
remove(Widget * w)1178 void AWindow::remove( Widget *w )
1179 {
1180 std::list<Widget*>::iterator it1;
1181 Widget *focusw;
1182
1183 if ( w == NULL ) return;
1184
1185 it1 = std::find( _childs.begin(), _childs.end(), w );
1186 if ( it1 == _childs.end() ) return; // not found
1187
1188 if ( _created == true ) w->destroy();
1189 focusw = getFocusOwner();
1190 if ( focusw != NULL ) {
1191 // check if the child has the focusowner
1192 if ( w->contains( focusw ) == true ) {
1193 invalidFocus();
1194 }
1195 }
1196 if ( container != NULL ) removeFromContainer( w );
1197 if ( _parent != NULL ) _parent->removeFromContainer( w );
1198 w->setParent( NULL );
1199 _childs.remove( w );
1200 }
1201
create()1202 int AWindow::create()
1203 {
1204 std::list<Widget*>::iterator it1;
1205 int res;
1206
1207 res = Widget::create();
1208 if ( _created == true ) {
1209 for ( it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
1210 (*it1)->create();
1211 }
1212 }
1213 return res;
1214 }
1215
destroy()1216 void AWindow::destroy()
1217 {
1218 std::list<Widget*>::iterator it1;
1219
1220 if ( _parent != NULL ) {
1221 _parent->removeKeyCallBack( this, NULL );
1222 }
1223
1224 if ( _created == true ) {
1225 for ( it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
1226 (*it1)->destroy();
1227 }
1228 }
1229 Widget::destroy();
1230 }
1231
setParent(class AWindow * parent)1232 int AWindow::setParent( class AWindow *parent )
1233 {
1234 // do not accept parent if already created
1235 //TODO it would be possible to destroy the window in
1236 // this case and reopen it
1237 if ( _created == true ) return 1;
1238 //TODO Wenn das Fenster schon ein Fokuselement haelt,
1239 // Dann sollte es dem parent uebergeben werden
1240 return Widget::setParent( parent );
1241 }
1242
setWMTitle()1243 int AWindow::setWMTitle()
1244 {
1245 Display *dsp;
1246 XClassHint classhint;
1247 XTextProperty windowname;
1248 char *tstr;
1249
1250 dsp = _aguix->getDisplay();
1251 if ( ( dsp == NULL ) || ( win == 0 ) ) return 1;
1252
1253 classhint.res_name = dupstring( _title.c_str() );
1254 classhint.res_class = dupstring( _aguix->getClassname().c_str() );
1255 XSetClassHint( dsp, win, &classhint );
1256 _freesafe( classhint.res_class );
1257 _freesafe( classhint.res_name );
1258
1259 tstr = dupstring( _title.c_str() );
1260
1261 if ( XStringListToTextProperty( &tstr, 1, &windowname ) != 0 ) {
1262 XTextProperty ticonname;
1263 if ( XStringListToTextProperty( &tstr, 1, &ticonname ) != 0 ) {
1264 XSetWMName( dsp, win, &windowname );
1265 XSetWMIconName( dsp, win, &ticonname );
1266 XFree( ticonname.value );
1267 }
1268 XFree( windowname.value );
1269 }
1270
1271 #if defined( X_HAVE_UTF8_STRING ) && !defined( DISABLE_UTF8_SUPPORT )
1272 if ( UTF8::getUTF8Mode() != UTF8::UTF8_DISABLED && UTF8::getCurrentEncoding() == UTF8::ENCODING_UTF8 ) {
1273 XTextProperty utf8name;
1274
1275 if ( XmbTextListToTextProperty( dsp, &tstr, 1, XUTF8StringStyle, &utf8name ) == Success ) {
1276 XSetTextProperty( dsp, win, &utf8name, _aguix->getAtom( AGUIX::NET_WM_NAME_ATOM ) );
1277 XSetTextProperty( dsp, win, &utf8name, _aguix->getAtom( AGUIX::NET_WM_ICON_NAME_ATOM ) );
1278 XFree( utf8name.value );
1279 }
1280 }
1281 #endif
1282
1283 _freesafe( tstr );
1284
1285 XStoreName( dsp, win, _title.c_str() );
1286
1287 return 0;
1288 }
1289
getChilds() const1290 const std::list<Widget*> &AWindow::getChilds() const
1291 {
1292 return _childs;
1293 }
1294
searchNextFocus(focus_search_mode_t & search_mode,const Widget * element,Widget ** new_element,Widget ** prev_element)1295 int AWindow::searchNextFocus( focus_search_mode_t &search_mode,
1296 const Widget *element,
1297 Widget **new_element,
1298 Widget **prev_element )
1299 {
1300 AWindow *twin;
1301
1302 if ( search_mode == SEARCH_FINISHED ) {
1303 return 0;
1304 } else if ( ( search_mode == SEARCH_NEXT ) && ( getAcceptFocus() == true ) && ( isVisible() == true ) ) {
1305 *new_element = this;
1306 search_mode = SEARCH_FINISHED;
1307 } else {
1308 if ( ( search_mode == SEARCH_WIDGET ) && ( this == element ) ) search_mode = SEARCH_NEXT;
1309 else if ( ( search_mode == SEARCH_WIDGET ) &&
1310 ( this != element ) &&
1311 ( prev_element != NULL ) &&
1312 ( getAcceptFocus() == true ) &&
1313 ( isVisible() == true ) )
1314 *prev_element = this;
1315
1316 for ( childs_it it1 = _childs.begin(); it1 != _childs.end(); it1++ ) {
1317 twin = dynamic_cast<AWindow*>( (*it1) );
1318 if ( twin != NULL ) {
1319 twin->searchNextFocus( search_mode, element, new_element, prev_element );
1320 } else {
1321 if ( ( search_mode == SEARCH_WIDGET ) && ( (*it1) == element ) ) search_mode = SEARCH_NEXT;
1322 else if ( ( search_mode == SEARCH_WIDGET ) &&
1323 ( (*it1) != element ) &&
1324 ( prev_element != NULL ) &&
1325 ( (*it1)->getAcceptFocus() == true ) &&
1326 ( (*it1)->isVisible() == true ) ) *prev_element = (*it1);
1327 else if ( ( search_mode == SEARCH_NEXT ) && ( (*it1)->getAcceptFocus() == true ) && ( (*it1)->isVisible() == true ) ) {
1328 *new_element = (*it1);
1329 search_mode = SEARCH_FINISHED;
1330 }
1331 }
1332 if ( search_mode == SEARCH_FINISHED ) break;
1333 }
1334 }
1335 return 0;
1336 }
1337
searchNextFocus(const Widget * current)1338 Widget *AWindow::searchNextFocus( const Widget *current )
1339 {
1340 focus_search_mode_t mode = SEARCH_WIDGET;
1341 Widget *new_element = NULL;
1342
1343 if ( current == NULL ) mode = SEARCH_NEXT;
1344 searchNextFocus( mode, current, &new_element );
1345
1346 if ( new_element == NULL ) {
1347 // no new focus element found
1348 // start again with mode NEXT
1349 mode = SEARCH_NEXT;
1350 searchNextFocus( mode, current, &new_element );
1351 }
1352
1353 // return element
1354 // it it is NULL it just means there is no focus element
1355 return new_element;
1356 }
1357
searchPrevFocus(const Widget * current)1358 Widget *AWindow::searchPrevFocus( const Widget *current )
1359 {
1360 focus_search_mode_t mode = SEARCH_WIDGET;
1361 Widget *new_element = NULL, *prev_element = NULL;
1362
1363 if ( current == NULL ) mode = SEARCH_NEXT;
1364 searchNextFocus( mode, current, &new_element, &prev_element );
1365
1366 if ( prev_element == NULL ) {
1367 // no prev found so start again with NULL element which
1368 // will go through all elements and should return the last
1369 // which is the only one which can not be found by the
1370 // first run
1371 mode = SEARCH_WIDGET;
1372 searchNextFocus( mode, NULL, &new_element, &prev_element );
1373 }
1374
1375 // return element
1376 // it it is NULL it just means there is no focus element
1377 return prev_element;
1378 }
1379
addWindowEvent(Window subwin,long mask)1380 int AWindow::addWindowEvent( Window subwin, long mask )
1381 {
1382 XWindowAttributes curattr;
1383
1384 if ( hasSubWin( subwin ) == false )
1385 return 1;
1386
1387 XGetWindowAttributes( _aguix->getDisplay(), subwin, &curattr );
1388 XSelectInput( _aguix->getDisplay(), subwin, curattr.your_event_mask | mask );
1389 return 0;
1390 }
1391
getMinWidth() const1392 int AWindow::getMinWidth() const
1393 {
1394 return minw;
1395 }
1396
getMinHeight() const1397 int AWindow::getMinHeight() const
1398 {
1399 return minh;
1400 }
1401
getMaxWidth() const1402 int AWindow::getMaxWidth() const
1403 {
1404 return maxw;
1405 }
1406
getMaxHeight() const1407 int AWindow::getMaxHeight() const
1408 {
1409 return maxh;
1410 }
1411
addKeyCallBack(CallBack * new_cb,int mode)1412 void AWindow::addKeyCallBack( CallBack *new_cb, int mode )
1413 {
1414 addKeyCallBack( this, new_cb, mode );
1415 }
1416
addKeyCallBack(AWindow * subwin,CallBack * new_cb,int mode)1417 void AWindow::addKeyCallBack( AWindow *subwin, CallBack *new_cb, int mode )
1418 {
1419 if ( _parent != NULL ) {
1420 _parent->addKeyCallBack( subwin, new_cb, mode );
1421 } else {
1422 key_listener_t k;
1423
1424 k.cb = new_cb;
1425 k.subwin = subwin;
1426 k.mode = mode;
1427 key_listener.push_back( k );
1428 }
1429 }
1430
removeKeyCallBack(AWindow * subwin,CallBack * cb)1431 void AWindow::removeKeyCallBack( AWindow *subwin, CallBack *cb )
1432 {
1433 if ( _parent != NULL ) {
1434 _parent->removeKeyCallBack( subwin, cb );
1435 } else {
1436 std::list<key_listener_t>::iterator it;
1437
1438 for ( it = key_listener.begin(); it != key_listener.end(); it++ ) {
1439 if ( (*it).subwin == subwin ) {
1440 if ( cb == NULL || (*it).cb == cb ) {
1441 it = key_listener.erase( it );
1442 }
1443 }
1444 }
1445 }
1446 }
1447
removeKeyCallBack(CallBack * cb)1448 void AWindow::removeKeyCallBack( CallBack *cb )
1449 {
1450 if ( cb == NULL ) return; // removal of all callbacks are not allowed from public interface
1451
1452 removeKeyCallBack( this, cb );
1453 }
1454
forbidCallBacks()1455 void AWindow::forbidCallBacks()
1456 {
1457 _callback_forbidden = true;
1458 if ( _parent != NULL ) _parent->forbidCallBacks();
1459 }
1460
permitCallBacks()1461 void AWindow::permitCallBacks()
1462 {
1463 if ( _parent != NULL ) _parent->permitCallBacks();
1464 _callback_forbidden = false;
1465 }
1466
callBackForbidden() const1467 bool AWindow::callBackForbidden() const
1468 {
1469 if ( _callback_forbidden == true ) return true;
1470 if ( _parent != NULL ) return _parent->callBackForbidden();
1471 return false;
1472 }
1473
toFront()1474 void AWindow::toFront()
1475 {
1476 if ( _created == false ) return;
1477 _aguix->WindowtoFront( win );
1478 }
1479
updateCont()1480 void AWindow::updateCont()
1481 {
1482 if ( container != NULL ) {
1483 container->resize( getWidth(), getHeight() );
1484 container->rearrange();
1485 }
1486 }
1487
isMaximized()1488 int AWindow::isMaximized()
1489 {
1490 Atom ret_type;
1491 int ret_format;
1492 unsigned long ret_len,ret_after;
1493 unsigned char *ret_prop;
1494
1495 int res = 0;
1496
1497 if ( _created == false ) return res;
1498
1499 if ( XGetWindowProperty( _aguix->getDisplay(),
1500 win,
1501 _aguix->getAtom( AGUIX::NET_WM_STATE ),
1502 0,
1503 32,
1504 False,
1505 AnyPropertyType,
1506 &ret_type,
1507 &ret_format,
1508 &ret_len,
1509 &ret_after,
1510 &ret_prop ) == Success ) {
1511 if ( ret_len > 0 &&
1512 ret_type == XA_ATOM &&
1513 ret_format == 32 ) {
1514 const Atom *atoms = (const Atom*)ret_prop;
1515 for ( unsigned long i = 0; i < ret_len; i++ ) {
1516 if ( atoms[i] == _aguix->getAtom( AGUIX::NET_WM_STATE_MAXIMIZED_HORZ ) ) {
1517 res |= 1;
1518 } else if ( atoms[i] == _aguix->getAtom( AGUIX::NET_WM_STATE_MAXIMIZED_VERT ) ) {
1519 res |= 2;
1520 }
1521 }
1522 }
1523 XFree( ret_prop );
1524 }
1525
1526 return res;
1527 }
1528
getRootPosition(int * x,int * y)1529 int AWindow::getRootPosition( int *x,
1530 int *y )
1531 {
1532 Window child;
1533
1534 if ( _created == false ) return 1;
1535
1536 if ( XTranslateCoordinates( _aguix->getDisplay(),
1537 win,
1538 DefaultRootWindow( _aguix->getDisplay() ),
1539 0, 0,
1540 x, y,
1541 &child ) == True ) {
1542 return 0;
1543 }
1544
1545 return 1;
1546 }
1547
forceOpenPosition(int x,int y,bool max_h,bool max_v)1548 void AWindow::forceOpenPosition( int x, int y,
1549 bool max_h,
1550 bool max_v )
1551 {
1552 m_open_pos_x = x;
1553 m_open_pos_y = y;
1554 m_open_max_h = max_h;
1555 m_open_max_v = max_v;
1556 m_force_open_position = true;
1557 }
1558
enableXDND()1559 void AWindow::enableXDND()
1560 {
1561 Atom version = 5;
1562
1563 XChangeProperty( _aguix->getDisplay(),
1564 win, _aguix->getAtom( AGUIX::XDNDAWARE ),
1565 XA_ATOM, 32,
1566 PropModeReplace, (unsigned char*)&version, 1 );
1567
1568 m_enable_xdnd = true;
1569 }
1570
acceptXDND()1571 bool AWindow::acceptXDND()
1572 {
1573 return m_enable_xdnd;
1574 }
1575
findWindowForRootPos(int rx,int ry)1576 Window AWindow::findWindowForRootPos( int rx, int ry )
1577 {
1578 int x, y;
1579 Window child;
1580 Window previous_child = None;
1581 Window current_window = win;
1582
1583 if ( XTranslateCoordinates( _aguix->getDisplay(),
1584 DefaultRootWindow( _aguix->getDisplay() ),
1585 current_window,
1586 rx, ry,
1587 &x, &y,
1588 &child ) != True ) {
1589 return None;
1590 }
1591
1592 previous_child = child;
1593
1594 while ( child != None ) {
1595 previous_child = child;
1596
1597 if ( XTranslateCoordinates( _aguix->getDisplay(),
1598 current_window,
1599 child,
1600 x, y,
1601 &x, &y,
1602 &child ) != True ) {
1603 return None;
1604 }
1605
1606 current_window = previous_child;
1607 }
1608
1609 return previous_child;
1610 }
1611
findWidgetForRootPos(int rx,int ry)1612 Widget *AWindow::findWidgetForRootPos( int rx, int ry )
1613 {
1614 Window child_win = findWindowForRootPos( rx, ry );
1615
1616 if ( child_win == None ) return NULL;
1617
1618 Widget *w = findWidgetForWindow( child_win );
1619
1620 if ( AWindow *awin = dynamic_cast< AWindow * >( w ) ) {
1621 return awin->findWidgetForWindow( child_win );
1622 }
1623
1624 return w;
1625 }
1626
applyIcon()1627 void AWindow::applyIcon()
1628 {
1629 const unsigned long *data = NULL;
1630 size_t data_length = 0;
1631
1632 if ( ! _aguix->getStandardIconData( &data, &data_length ) ) {
1633 return;
1634 }
1635
1636 XChangeProperty( _aguix->getDisplay(),
1637 win,
1638 _aguix->getAtom( AGUIX::NET_WM_ICON_ATOM ),
1639 _aguix->getAtom( AGUIX::CARDINAL_ATOM ),
1640 32, PropModeReplace, (const unsigned char*)data, data_length );
1641 }
1642