/*************************************************************************** CWindow.cpp (c) 2000-2009 BenoƮt Minisini This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ***************************************************************************/ #define __CWINDOW_CPP #include #include #include #include #include #include #include #include //Added by qt3to4: #include #include #include #include #include #include #include #include #include #include #include #include #include "main.h" #ifndef NO_X_WINDOW #include #include #endif #include "gambas.h" #include "CWidget.h" #include "CMenu.h" #include "CKey.h" #include "CDraw.h" #include "CWindow.h" #ifndef NO_X_WINDOW #include "x11.h" #undef FontChange #else enum { _NET_WM_WINDOW_TYPE_NORMAL, _NET_WM_WINDOW_TYPE_DESKTOP, _NET_WM_WINDOW_TYPE_DOCK, _NET_WM_WINDOW_TYPE_TOOLBAR, _NET_WM_WINDOW_TYPE_MENU, _NET_WM_WINDOW_TYPE_UTILITY, _NET_WM_WINDOW_TYPE_SPLASH, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_WINDOW_TYPE_DROPDOWN_MENU, _NET_WM_WINDOW_TYPE_POPUP_MENU, _NET_WM_WINDOW_TYPE_TOOLTIP, _NET_WM_WINDOW_TYPE_NOTIFICATION, _NET_WM_WINDOW_TYPE_COMBO, _NET_WM_WINDOW_TYPE_DND }; #endif //#define DEBUG_WINDOW 1 DECLARE_EVENT(EVENT_Open); DECLARE_EVENT(EVENT_Close); DECLARE_EVENT(EVENT_Activate); DECLARE_EVENT(EVENT_Deactivate); DECLARE_EVENT(EVENT_Move); DECLARE_EVENT(EVENT_Resize); DECLARE_EVENT(EVENT_Show); DECLARE_EVENT(EVENT_Hide); DECLARE_EVENT(EVENT_Title); DECLARE_EVENT(EVENT_Icon); DECLARE_METHOD(CWINDOW_show); CWINDOW *CWINDOW_Main = 0; CWINDOW *CWINDOW_Current = 0; CWINDOW *CWINDOW_LastActive = 0; CWINDOW *CWINDOW_Active = 0; int CWINDOW_Embedder = 0; bool CWINDOW_Embedded = false; static int CWINDOW_EmbedState = 0; #ifndef NO_X_WINDOW void CWINDOW_change_property(QWidget *w, Atom property, bool set) { if (!w->isWindow()) return; X11_window_change_property(w->winId(), w->isVisible(), property, set); } bool CWINDOW_has_property(QWidget *w, Atom property) { if (!w->isWindow()) return false; return X11_window_has_property(w->winId(), property); } #endif // Fix a QT little boring visual bug on menubars #if 0 void CWINDOW_fix_menubar(CWINDOW *window) { if (window && window->menuBar) { QWidget *save = qApp->focusWidget(); window->menuBar->setFocus(); QKeyEvent e(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier); qApp->sendEvent(window->menuBar, &e); if (save) save->setFocus(); } } #endif /*---- Utility routines --------------------------------------------------------------*/ static void clear_mask(CWINDOW *_object) { WINDOW->clearMask(); if (THIS->toplevel) { #ifndef NO_X_WINDOW bool v = !WINDOW->isHidden() && WINDOW->isVisible(); //WINDOW->setBorder(WINDOW->hasBorder(), true); //WINDOW->setResizable(WINDOW->isResizable(), true); if (v && THIS->reallyMasked) { X11_window_remap(WINDOW->winId()); WINDOW->initProperties(); } #endif } } void CWINDOW_define_mask(CWINDOW *_object) { QPixmap background; QColor c; QPalette palette; //qDebug("define_mask: (%s %p) picture = %p masked = %d", GB.GetClassName(THIS), THIS, THIS->picture, THIS->masked); //if (THIS->embedded) // return; if (THIS->picture) background = *(THIS->picture->pixmap); if (background.isNull()) { clear_mask(THIS); THIS->reallyMasked = false; THIS->container->setPixmap(0); //THIS->container->setPalette(WINDOW->palette()); } else { if (THIS->masked && background.hasAlpha()) { THIS->reallyMasked = true; WINDOW->setMask(background.mask()); } else { clear_mask(THIS); THIS->reallyMasked = false; } THIS->container->setPixmap(THIS->picture->pixmap); } THIS->container->update(); } static bool emit_open_event(void *_object) { //if (THIS->opening) // return true; if (THIS->opened) return false; CWIDGET_clear_flag(THIS, WF_CLOSED); THIS->opened = true; if (!THIS->minw && !THIS->minh) { THIS->minw = THIS->w; THIS->minh = THIS->h; } #if DEBUG_WINDOW qDebug("emit_open_event: %s %p", GB.GetClassName(THIS), THIS); #endif //THIS->opening = true; GB.Raise(THIS, EVENT_Open, 0); //THIS->opening = false; if (CWIDGET_test_flag(THIS, WF_CLOSED)) { #if DEBUG_WINDOW qDebug("emit_open_event: %s %p [CANCELED]", GB.GetClassName(THIS), THIS); #endif THIS->opened = false; return true; } THIS->opened = true; THIS->hidden = false; return false; } static void handle_focus(CWINDOW *_object) { if (THIS->focus) { //qDebug("handle_focus"); THIS->focus->widget->setFocus(); GB.Unref(POINTER(&THIS->focus)); THIS->focus = NULL; } } static void post_show_event(void *_object) { GB.Raise(THIS, EVENT_Move, 0); GB.Raise(THIS, EVENT_Resize, 0); handle_focus(THIS); } static void reparent_window(CWINDOW *_object, void *parent, bool move, int x = 0, int y = 0) { QPoint p; QWidget *newParentWidget; if (move) { p.setX(x); p.setY(y); } else if (THIS->toplevel) { p.setX(THIS->x); p.setY(THIS->y); } else p = WIDGET->pos(); if (!parent) newParentWidget = 0; else { if (GB.CheckObject(parent)) return; newParentWidget = QCONTAINER(parent); } if (newParentWidget != WINDOW->parentWidget()) { //qDebug("reparent_window: -> %s %p", parent ? ((CWIDGET *)parent)->name : "", parent); WINDOW->doReparent(newParentWidget, p); WINDOW->setResizable(WINDOW->isResizable(), true); } else CWIDGET_move(THIS, p.x(), p.y()); } void CWINDOW_ensure_active_window() { void *_object = CWINDOW_Active; if (THIS) WINDOW->activateWindow(); } /*************************************************************************** Window ***************************************************************************/ static void show_later(CWINDOW *_object) { /* If the user has explicitely hidden the window since the posting of this routines then do nothing */ //qDebug("show_later %s %p: hidden = %d", GB.GetClassName(THIS), THIS, THIS->hidden); if (!THIS->hidden && WIDGET) { if (!emit_open_event(THIS)) CWIDGET_set_visible((CWIDGET *)THIS, true); } GB.Unref(POINTER(&_object)); } BEGIN_METHOD(CWINDOW_new, GB_OBJECT parent) MyMainWindow *win = 0; MyContainer *container; #ifndef NO_X_WINDOW QX11EmbedWidget *client = 0; #endif const char *name = GB.GetClassName(THIS); //THIS->widget.flag.fillBackground = true; if (MISSING(parent) || !VARG(parent)) { #ifndef NO_X_WINDOW if (CWINDOW_Embedder && !CWINDOW_Embedded) { client = new QX11EmbedWidget; win = new MyMainWindow(client, name, true); container = new MyContainer(win); container->raise(); THIS->embedded = true; THIS->toplevel = false; THIS->xembed = true; } else #endif { //win = new MyMainWindow(CWINDOW_Main ? (MyMainWindow *)QWIDGET(CWINDOW_Main) : 0, name); win = new MyMainWindow(0, name); container = new MyContainer(win); container->raise(); THIS->embedded = false; THIS->toplevel = true; THIS->xembed = false; } } else { if (GB.Conv((GB_VALUE *)(void *)ARG(parent), (GB_TYPE)CLASS_Container)) return; //frame = new MyEmbeddedWindow(QCONTAINER(VARG(parent))); //frame->setName(name); //container = frame; //THIS->embedded = true; //THIS->toplevel = false; //container->installEventFilter(&CWindow::manager); //CWIDGET_new(frame, (void *)_object, NULL); win = new MyMainWindow(QCONTAINER(VARG(parent)), name, true); container = new MyContainer(win); container->raise(); THIS->embedded = true; THIS->toplevel = false; THIS->xembed = false; } /*else { GB.Error("The parent of a Window must be a Container or a Workspace"); return; }*/ THIS->container = container; CWIDGET_new(win, (void *)_object, true); //container->setPaletteBackgroundColor(Qt::yellow); //container->setBackgroundOrigin(QWidget::WindowOrigin); //qDebug("CWINDOW_new: %p: %s", THIS, GB.Debug.GetCurrentPosition()); if (win) { win->_object = THIS; win->installEventFilter(&CWindow::manager); } if (THIS->toplevel || THIS->xembed) { CWindow::insertTopLevel(THIS); if (CWINDOW_Main == 0) { #if DEBUG_WINDOW qDebug("CWINDOW_Main -> %p", THIS); #endif CWINDOW_Main = THIS; } } #ifndef NO_X_WINDOW if (THIS->xembed) { CWINDOW_Embedded = true; QObject::connect(XEMBED, SIGNAL(embedded()), &CWindow::manager, SLOT(embedded())); QObject::connect(XEMBED, SIGNAL(containerClosed()), &CWindow::manager, SLOT(closed())); QObject::connect(XEMBED, SIGNAL(error(int)), &CWindow::manager, SLOT(error())); //qDebug("XEMBED: EmbedInto %ld", CWINDOW_Embedder); XEMBED->embedInto(CWINDOW_Embedder); //qDebug("XEMBED: show"); //XEMBED->show(); //define_mask(THIS); for(;;) { MAIN_process_events(); if (CWINDOW_EmbedState) break; usleep(10000); } //qDebug("XEMBED: EmbedState: %d", CWINDOW_EmbedState); if (CWINDOW_EmbedState == EMBED_ERROR) { CWINDOW_Embedded = false; CWINDOW_Embedder = 0; GB.Error("Embedding has failed"); } } #endif if (THIS->embedded && !THIS->xembed) { /* ### This can call post_show_event() directly, whereas the function is not terminated */ #if DEBUG_WINDOW qDebug("post show_later %s %p", GB.GetClassName(THIS), THIS); #endif GB.Ref(THIS); //show_later(THIS); GB.Post((void (*)())show_later, (intptr_t)THIS); //WIDGET->show(); } else THIS->hidden = TRUE; THIS->showMenuBar = true; END_METHOD BEGIN_METHOD_VOID(CFORM_new) if (!GB.Parent(_object)) GB.Attach(_object, _object, "Form"); END_METHOD BEGIN_METHOD_VOID(CFORM_main) CWINDOW *form = (CWINDOW *)GB.AutoCreate(GB.GetClass(NULL), 0); //if (!((MyMainWindow *)form->widget.widget)->isHidden()) //if (!form->hidden) CWINDOW_show(form, NULL); END_METHOD BEGIN_METHOD(CFORM_load, GB_OBJECT parent) //qDebug("CFORM_load"); reparent_window((CWINDOW *)GB.AutoCreate(GB.GetClass(NULL), 0), VARGOPT(parent, 0), false); END_METHOD BEGIN_METHOD_VOID(CWINDOW_free) //qDebug("CWINDOW_free"); GB.StoreObject(NULL, POINTER(&(THIS->icon))); GB.StoreObject(NULL, POINTER(&(THIS->picture))); GB.Unref(POINTER(&THIS->focus)); END_METHOD BEGIN_METHOD_VOID(CWINDOW_next) int index = ENUM(int); if (index >= CWindow::list.count()) { GB.StopEnum(); return; } GB.ReturnObject(CWindow::list.at(index)); ENUM(int) = index + 1; END_METHOD BEGIN_PROPERTY(CWINDOW_count) GB.ReturnInteger(CWindow::list.count()); END_PROPERTY BEGIN_METHOD(CWINDOW_get_from_id, GB_INTEGER id) QWidget *wid = QWidget::find(VARG(id)); //qDebug("id = %d wid = %p", PARAM(id), wid); if (wid != 0 && wid->isWindow()) { //qDebug("-> %p", CWidget::getReal(wid)); GB.ReturnObject(CWidget::getReal(wid)); } else { //qDebug("-> %p", 0); GB.ReturnNull(); } END_METHOD static bool do_close(CWINDOW *_object, int ret, bool destroyed = false) { bool closed; #if DEBUG_WINDOW qDebug("do_close: (%s %p) %d %d", GB.GetClassName(THIS), THIS, THIS->closing, CWIDGET_test_flag(THIS, WF_CLOSED)); #endif if (THIS->closing || CWIDGET_test_flag(THIS, WF_CLOSED)) // || WIDGET->isHidden()) return false; if (!THIS->toplevel) { //qDebug("Close event: %s %p opened = %d", GB.GetClassName(THIS), THIS, THIS->opened); if (THIS->opened) { THIS->closing = true; closed = !GB.Raise(THIS, EVENT_Close, 0); THIS->closing = false; } else closed = true; if (destroyed || closed) { CWIDGET_set_flag(THIS, WF_CLOSED); THIS->opened = false; } if (closed) { WIDGET->hide(); if (!CWIDGET_test_flag(_object, WF_PERSISTENT)) CWIDGET_destroy((CWIDGET *)THIS); } } else { if (!THIS->opened) { #if DEBUG_WINDOW qDebug("send close event"); #endif QCloseEvent e; QApplication::sendEvent(WINDOW, &e); closed = e.isAccepted(); } else { #if DEBUG_WINDOW qDebug("call WINDOW->close()"); #endif closed = WINDOW->close(); } #if DEBUG_WINDOW qDebug("--> closed = %d", closed); #endif } #if 0 if (closed || destroyed) { if (CWINDOW_Active == THIS) CWINDOW_activate(CWidget::get(WIDGET->parentWidget())); if (CWINDOW_LastActive == THIS) { //GB.Unref(POINTER(&CWINDOW_LastActive)); CWINDOW_LastActive = 0; //qDebug("CWINDOW_LastActive = 0"); } THIS->opened = FALSE; } #endif if (closed) THIS->ret = ret; return (!closed); } BEGIN_METHOD(CWINDOW_close, GB_INTEGER ret) int ret = VARGOPT(ret, 0); GB.ReturnBoolean(do_close(THIS, ret)); END_METHOD BEGIN_METHOD_VOID(CWINDOW_raise) if (!THIS->toplevel) { if (!WIDGET->isVisible()) CWIDGET_set_visible((CWIDGET *)THIS, true); WIDGET->raise(); } else { if (!WINDOW->isVisible()) WINDOW->showActivate(); else WINDOW->raise(); } END_METHOD BEGIN_METHOD_VOID(CWINDOW_show) if (emit_open_event(THIS)) return; if (!THIS->toplevel) { CWIDGET_set_visible((CWIDGET *)THIS, true); #ifndef NO_X_WINDOW if (THIS->xembed) XEMBED->show(); #endif post_show_event(THIS); } else { WINDOW->showActivate(); //parent ? parent->widget.widget : 0); //THIS->widget.flag.visible = true; } END_METHOD BEGIN_METHOD_VOID(CWINDOW_hide) THIS->hidden = true; if (THIS->toplevel && WINDOW->isModal()) { do_close(THIS, 0); //THIS->widget.flag.visible = false; } else CWIDGET_set_visible((CWIDGET *)THIS, false); END_METHOD BEGIN_METHOD_VOID(CWINDOW_show_modal) THIS->ret = 0; if (!emit_open_event(THIS)) { if (THIS->toplevel) { //THIS->widget.flag.visible = true; WINDOW->showModal(); //THIS->widget.flag.visible = false; } } GB.ReturnInteger(THIS->ret); END_METHOD BEGIN_METHOD(Window_ShowPopup, GB_INTEGER x; GB_INTEGER y) QPoint pos; if (MISSING(x) || MISSING(y)) pos = QCursor::pos(); else pos = QPoint(VARG(x), VARG(y)); THIS->ret = 0; if (THIS->toplevel) { if (!emit_open_event(THIS)) WINDOW->showPopup(pos); } GB.ReturnInteger(THIS->ret); END_METHOD BEGIN_PROPERTY(CWINDOW_modal) if (THIS->toplevel) GB.ReturnBoolean(WINDOW->isModal()); else GB.ReturnBoolean(false); END_PROPERTY BEGIN_PROPERTY(CWINDOW_top_level) GB.ReturnBoolean(THIS->toplevel); END_PROPERTY /*BEGIN_METHOD_VOID(CWINDOW_dialog) CWINDOW *win; GB.New(POINTER(&win), GB.GetClass(NULL), NULL, NULL); win->ret = 0; ((MyMainWindow *)win->widget.widget)->showModal(); GB.ReturnInteger(win->ret); END_METHOD*/ BEGIN_PROPERTY(CWINDOW_persistent) /* if (READ_PROPERTY) GB.ReturnBoolean(WIDGET->isPersistent()); else WIDGET->setPersistent(PROPERTY(char) != 0); */ if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnBoolean(true); } else { if (READ_PROPERTY) GB.ReturnBoolean(CWIDGET_test_flag(THIS, WF_PERSISTENT)); else { if (VPROP(GB_BOOLEAN)) CWIDGET_set_flag(THIS, WF_PERSISTENT); else CWIDGET_clear_flag(THIS, WF_PERSISTENT); } } END_PROPERTY BEGIN_PROPERTY(CWINDOW_text) if (READ_PROPERTY) GB.ReturnNewZeroString(TO_UTF8(WIDGET->windowTitle())); else { QString s = QSTRING_PROP(); THIS->title = s.length() > 0; WIDGET->setWindowTitle(s); GB.Raise(THIS, EVENT_Title, 0); } END_PROPERTY #if 0 BEGIN_PROPERTY(CWINDOW_border) if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnInteger(0); } else { if (READ_PROPERTY) GB.ReturnInteger(WINDOW->getBorder()); else WINDOW->setBorder(VPROP(GB_INTEGER)); } END_PROPERTY #endif BEGIN_PROPERTY(CWINDOW_border) if (READ_PROPERTY) GB.ReturnBoolean(WINDOW->hasBorder()); else WINDOW->setBorder(VPROP(GB_BOOLEAN)); END_PROPERTY BEGIN_PROPERTY(CWINDOW_resizable) if (READ_PROPERTY) GB.ReturnBoolean(WINDOW->isResizable()); else WINDOW->setResizable(VPROP(GB_BOOLEAN)); END_PROPERTY BEGIN_PROPERTY(CWINDOW_icon) if (READ_PROPERTY) GB.ReturnObject(THIS->icon); else { SET_PIXMAP(WIDGET->setWindowIcon, &(THIS->icon), PROP(GB_OBJECT)); GB.Raise(THIS, EVENT_Icon, 0); } END_PROPERTY BEGIN_PROPERTY(CWINDOW_picture) if (READ_PROPERTY) GB.ReturnObject(THIS->picture); else { CPICTURE *new_pict = (CPICTURE *)VPROP(GB_OBJECT); if (new_pict != THIS->picture) { CPICTURE *old = THIS->picture; GB.Ref(new_pict); THIS->picture = new_pict; //CWINDOW_define_mask(THIS); CWIDGET_reset_color((CWIDGET *)THIS); GB.Unref(POINTER(&old)); } } END_PROPERTY BEGIN_PROPERTY(CWINDOW_mask) /*if (THIS->embedded) { if (READ_PROPERTY) GB.ReturnBoolean(FALSE); } else*/ { if (READ_PROPERTY) GB.ReturnBoolean(THIS->masked); else { bool new_masked = VPROP(GB_BOOLEAN); if (new_masked != THIS->masked) { THIS->masked = new_masked; //CWINDOW_define_mask(THIS); CWIDGET_reset_color((CWIDGET *)THIS); } } } END_PROPERTY #if 0 BEGIN_PROPERTY(CWINDOW_state) if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnInteger(0); } else { if (READ_PROPERTY) GB.ReturnInteger(WINDOW->getState()); else WINDOW->setState(VPROP(GB_INTEGER)); } END_PROPERTY static void show_window_state(void *_object) { THIS->stateChange = false; if (WINDOW) { if (WINDOW->windowState() & Qt::WindowMinimized) WINDOW->showMinimized(); else if (WINDOW->windowState() & Qt::WindowFullScreen) WINDOW->showFullScreen(); else if (WINDOW->windowState() & Qt::WindowMaximized) WINDOW->showMaximized(); else WINDOW->showNormal(); } //qDebug("show_window_state %s %p", GB.GetClassName(THIS), THIS); GB.Unref(POINTER(&_object)); } #endif static void manage_window_state(void *_object, void *_param, Qt::WindowState state) { if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnBoolean(FALSE); } else { if (READ_PROPERTY) GB.ReturnBoolean(WINDOW->windowState() & state); else { if (VPROP(GB_BOOLEAN)) WINDOW->setWindowState(WINDOW->windowState() | state); else WINDOW->setWindowState(WINDOW->windowState() & ~state); if (WINDOW->isVisible()) { if (WINDOW->windowState() & Qt::WindowMinimized) WINDOW->showMinimized(); else if (WINDOW->windowState() & Qt::WindowFullScreen) WINDOW->showFullScreen(); else if (WINDOW->windowState() & Qt::WindowMaximized) WINDOW->showMaximized(); else WINDOW->showNormal(); } /*if (WINDOW->isVisible() && !THIS->stateChange) { THIS->stateChange = true; //qDebug("post show_window_state %s %p", GB.GetClassName(THIS), THIS); GB.Ref(THIS); GB.Post((GB_POST_FUNC)show_window_state, (intptr_t)THIS); }*/ } } } BEGIN_PROPERTY(CWINDOW_minimized) manage_window_state(_object, _param, Qt::WindowMinimized); END_PROPERTY BEGIN_PROPERTY(CWINDOW_maximized) manage_window_state(_object, _param, Qt::WindowMaximized); END_PROPERTY BEGIN_PROPERTY(CWINDOW_full_screen) manage_window_state(_object, _param, Qt::WindowFullScreen); END_PROPERTY #ifdef NO_X_WINDOW //------------------------------------------------------------------------------ BEGIN_PROPERTY(CWINDOW_stacking) if (READ_PROPERTY) GB.ReturnInteger(0); END_PROPERTY BEGIN_PROPERTY(CWINDOW_top_only) if (READ_PROPERTY) GB.ReturnBoolean(FALSE); END_PROPERTY BEGIN_PROPERTY(CWINDOW_skip_taskbar) if (READ_PROPERTY) GB.ReturnBoolean(FALSE); END_PROPERTY BEGIN_PROPERTY(CWINDOW_sticky) if (READ_PROPERTY) GB.ReturnBoolean(FALSE); END_PROPERTY BEGIN_PROPERTY(CWINDOW_type) if (READ_PROPERTY) GB.ReturnInteger(0); END_PROPERTY BEGIN_PROPERTY(Window_Utility) if (READ_PROPERTY) GB.ReturnBoolean(FALSE); END_PROPERTY #else //------------------------------------------------------------------------------------------- static void manage_window_property(void *_object, void *_param, Atom property) { if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnBoolean(FALSE); } else { if (READ_PROPERTY) GB.ReturnBoolean(CWINDOW_has_property(WINDOW, property)); else CWINDOW_change_property(WINDOW, property, VPROP(GB_BOOLEAN)); } } BEGIN_PROPERTY(CWINDOW_stacking) int p; if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnInteger(0); return; } if (READ_PROPERTY) { GB.ReturnInteger(THIS->stacking); } else { p = VPROP(GB_INTEGER); if (p >= 0 && p <= 2) { THIS->stacking = p; WINDOW->initProperties(); } } END_PROPERTY BEGIN_PROPERTY(CWINDOW_top_only) if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnBoolean(FALSE); return; } if (READ_PROPERTY) { GB.ReturnBoolean(THIS->stacking == 1); } else { THIS->stacking = VPROP(GB_BOOLEAN) ? 1 : 0; WINDOW->initProperties(); } END_PROPERTY BEGIN_PROPERTY(CWINDOW_skip_taskbar) manage_window_property(_object, _param, X11_atom_net_wm_state_skip_taskbar); if (!READ_PROPERTY) THIS->skipTaskbar = VPROP(GB_BOOLEAN); END_PROPERTY BEGIN_PROPERTY(CWINDOW_sticky) if (!THIS->toplevel) { if (READ_PROPERTY) GB.ReturnBoolean(FALSE); return; } if (READ_PROPERTY) GB.ReturnBoolean(THIS->sticky); else { THIS->sticky = VPROP(GB_BOOLEAN); X11_window_set_desktop(WINDOW->winId(), WINDOW->isVisible(), THIS->sticky ? 0xFFFFFFFF : X11_get_current_desktop()); } END_PROPERTY BEGIN_PROPERTY(CWINDOW_type) if (READ_PROPERTY) GB.ReturnInteger(WINDOW->getType()); else WINDOW->setType(VPROP(GB_INTEGER)); END_PROPERTY BEGIN_PROPERTY(Window_Utility) if (READ_PROPERTY) GB.ReturnBoolean(WINDOW->getType() == _NET_WM_WINDOW_TYPE_UTILITY); else WINDOW->setType(VPROP(GB_BOOLEAN) ? _NET_WM_WINDOW_TYPE_UTILITY : _NET_WM_WINDOW_TYPE_NORMAL); END_PROPERTY #endif //------------------------------------------------------------------------------------------ BEGIN_METHOD_VOID(CWINDOW_center) if (!THIS->toplevel) return; WINDOW->center(true); END_METHOD BEGIN_METHOD_VOID(CWINDOW_delete) //qDebug("CWINDOW_delete %p", THIS); do_close(THIS, 0); if (THIS->toplevel) CWIDGET_clear_flag(THIS, WF_PERSISTENT); CWIDGET_destroy((CWIDGET *)THIS); END_METHOD BEGIN_PROPERTY(CWINDOW_visible) if (READ_PROPERTY) GB.ReturnBoolean(!WINDOW->isHidden()); else { if (VPROP(GB_BOOLEAN)) CWINDOW_show(_object, _param); else CWINDOW_hide(_object, _param); } END_PROPERTY BEGIN_PROPERTY(CWINDOW_control_count) QList list = WINDOW->findChildren(); int i; int n = 0; for (i = 0; i < list.count(); i++) { if (CWidget::getReal(list.at(i))) n++; } GB.ReturnInteger(n); END_PROPERTY BEGIN_METHOD_VOID(CWINDOW_control_next) QList children = WINDOW->findChildren(); CWIDGET *control; int index; index = ENUM(int); control = NULL; do { if (index >= children.count()) { GB.StopEnum(); return; } control = CWidget::getReal(children.at(index)); index++; } while (!control); ENUM(int) = index; GB.ReturnObject(control); END_PROPERTY BEGIN_METHOD(CWINDOW_reparent, GB_OBJECT container; GB_INTEGER x; GB_INTEGER y) //qDebug("CWINDOW_reparent"); reparent_window(THIS, VARG(container), !MISSING(x) && !MISSING(y), VARG(x), VARG(y)); END_METHOD BEGIN_METHOD(CWINDOW_get, GB_STRING name) GB.ReturnObject(WINDOW->names[GB.ToZeroString(ARG(name))]); END_METHOD BEGIN_PROPERTY(CWINDOW_closed) GB.ReturnBoolean(!THIS->opened); END_PROPERTY /***************************************************************************/ BEGIN_PROPERTY(CWINDOW_menu_count) if (THIS->menuBar) GB.ReturnInteger(THIS->menuBar->actions().count()); else GB.ReturnInteger(0); END_PROPERTY BEGIN_METHOD_VOID(CWINDOW_menu_next) int index; if (!THIS->menuBar) { GB.StopEnum(); return; } index = ENUM(int); if (index >= THIS->menuBar->actions().count()) { GB.StopEnum(); return; } GB.ReturnObject(CMenu::dict[THIS->menuBar->actions().at(index)]); ENUM(int) = index + 1; END_PROPERTY BEGIN_METHOD(CWINDOW_menu_get, GB_INTEGER index) int index = VARG(index); if (!THIS->menuBar || index < 0 || index >= THIS->menuBar->actions().count()) { GB.Error(GB_ERR_BOUND); return; } GB.ReturnObject(CMenu::dict[THIS->menuBar->actions().at(index)]); END_PROPERTY static bool are_menus_visible(void *_object) { return !THIS->hideMenuBar && THIS->showMenuBar; } static void set_menus_visible(void *_object, bool v) { THIS->showMenuBar = v; WINDOW->configure(); } BEGIN_PROPERTY(CWINDOW_menu_visible) if (READ_PROPERTY) GB.ReturnBoolean(are_menus_visible(THIS)); else set_menus_visible(THIS, VPROP(GB_BOOLEAN)); END_PROPERTY BEGIN_METHOD_VOID(CWINDOW_menu_show) set_menus_visible(THIS, true); END_METHOD BEGIN_METHOD_VOID(CWINDOW_menu_hide) set_menus_visible(THIS, false); END_METHOD BEGIN_PROPERTY(Window_Opacity) if (READ_PROPERTY) GB.ReturnInteger(WIDGET->windowOpacity() * 100); else { double opacity = VPROP(GB_INTEGER) / 100.0; if (opacity < 0.0) opacity = 0.0; else if (opacity > 1.0) opacity = 1.0; WIDGET->setWindowOpacity(opacity); } END_PROPERTY BEGIN_PROPERTY(Window_Screen) GB.ReturnInteger(QApplication::desktop()->screenNumber(WIDGET)); END_PROPERTY /***************************************************************************/ GB_DESC CWindowMenusDesc[] = { GB_DECLARE(".WindowMenus", 0), GB_VIRTUAL_CLASS(), GB_METHOD("_next", "Menu", CWINDOW_menu_next, NULL), GB_METHOD("_get", "Menu", CWINDOW_menu_get, "(Index)i"), GB_PROPERTY_READ("Count", "i", CWINDOW_menu_count), GB_METHOD("Show", NULL, CWINDOW_menu_show, NULL), GB_METHOD("Hide", NULL, CWINDOW_menu_hide, NULL), GB_PROPERTY("Visible", "b", CWINDOW_menu_visible), GB_END_DECLARE }; GB_DESC CWindowControlsDesc[] = { GB_DECLARE(".WindowControls", 0), GB_VIRTUAL_CLASS(), GB_METHOD("_next", "Control", CWINDOW_control_next, NULL), GB_METHOD("_get", "Control", CWINDOW_get, "(Name)s"), GB_PROPERTY_READ("Count", "i", CWINDOW_control_count), GB_END_DECLARE }; GB_DESC CWindowTypeDesc[] = { GB_DECLARE("WindowType", 0), GB_VIRTUAL_CLASS(), GB_CONSTANT("Normal", "i", _NET_WM_WINDOW_TYPE_NORMAL), GB_CONSTANT("Dock", "i", _NET_WM_WINDOW_TYPE_DOCK), GB_CONSTANT("Toolbar", "i", _NET_WM_WINDOW_TYPE_TOOLBAR), GB_CONSTANT("Menu", "i", _NET_WM_WINDOW_TYPE_MENU), GB_CONSTANT("Utility", "i", _NET_WM_WINDOW_TYPE_UTILITY), GB_CONSTANT("Splash", "i", _NET_WM_WINDOW_TYPE_SPLASH), GB_CONSTANT("Dialog", "i", _NET_WM_WINDOW_TYPE_DIALOG), GB_CONSTANT("DropDownMenu", "i", _NET_WM_WINDOW_TYPE_DROPDOWN_MENU), GB_CONSTANT("PopupMenu", "i", _NET_WM_WINDOW_TYPE_POPUP_MENU), GB_CONSTANT("Tooltip", "i", _NET_WM_WINDOW_TYPE_TOOLTIP), GB_CONSTANT("Notification", "i", _NET_WM_WINDOW_TYPE_NOTIFICATION), GB_CONSTANT("Combo", "i", _NET_WM_WINDOW_TYPE_COMBO), GB_CONSTANT("DragAndDrop", "i", _NET_WM_WINDOW_TYPE_DND), GB_CONSTANT("Desktop", "i", _NET_WM_WINDOW_TYPE_DESKTOP), GB_END_DECLARE }; GB_DESC CWindowDesc[] = { GB_DECLARE("Window", sizeof(CWINDOW)), GB_INHERITS("Container"), GB_CONSTANT("Normal", "i", 0), GB_CONSTANT("Above", "i", 1), GB_CONSTANT("Below", "i", 2), GB_METHOD("_new", NULL, CWINDOW_new, "[(Parent)Control;]"), GB_METHOD("_free", NULL, CWINDOW_free, NULL), GB_METHOD("_get", "Control", CWINDOW_get, "(Name)s"), GB_METHOD("Close", "b", CWINDOW_close, "[(Return)i]"), GB_METHOD("Raise", NULL, CWINDOW_raise, NULL), GB_METHOD("Show", NULL, CWINDOW_show, NULL), GB_METHOD("Hide", NULL, CWINDOW_hide, NULL), GB_METHOD("ShowModal", "i", CWINDOW_show_modal, NULL), GB_METHOD("ShowDialog", "i", CWINDOW_show_modal, NULL), GB_METHOD("ShowPopup", "i", Window_ShowPopup, "[(X)i(Y)i]"), GB_METHOD("Center", NULL, CWINDOW_center, NULL), GB_PROPERTY_READ("Modal", "b", CWINDOW_modal), GB_PROPERTY_READ("TopLevel", "b", CWINDOW_top_level), GB_PROPERTY_READ("Closed", "b", CWINDOW_closed), GB_METHOD("Delete", NULL, CWINDOW_delete, NULL), GB_METHOD("Reparent", NULL, CWINDOW_reparent, "(Container)Container;[(X)i(Y)i]"), GB_PROPERTY("Persistent", "b", CWINDOW_persistent), GB_PROPERTY("Text", "s", CWINDOW_text), GB_PROPERTY("Title", "s", CWINDOW_text), GB_PROPERTY("Caption", "s", CWINDOW_text), GB_PROPERTY("Icon", "Picture", CWINDOW_icon), GB_PROPERTY("Picture", "Picture", CWINDOW_picture), GB_PROPERTY("Mask", "b", CWINDOW_mask), GB_PROPERTY("Minimized", "b", CWINDOW_minimized), GB_PROPERTY("Maximized", "b", CWINDOW_maximized), GB_PROPERTY("FullScreen", "b", CWINDOW_full_screen), GB_PROPERTY("TopOnly", "b", CWINDOW_top_only), GB_PROPERTY("Stacking", "i", CWINDOW_stacking), GB_PROPERTY("Sticky", "b", CWINDOW_sticky), GB_PROPERTY("SkipTaskbar", "b", CWINDOW_skip_taskbar), GB_PROPERTY("Visible", "b", CWINDOW_visible), GB_PROPERTY("Opacity", "i", Window_Opacity), GB_PROPERTY("Arrangement", "i", CCONTAINER_arrangement), GB_PROPERTY("Padding", "i", CCONTAINER_padding), GB_PROPERTY("Spacing", "b", CCONTAINER_spacing), GB_PROPERTY("Margin", "b", CCONTAINER_margin), GB_PROPERTY("AutoResize", "b", CCONTAINER_auto_resize), GB_PROPERTY("Type", "i", CWINDOW_type), GB_PROPERTY("Utility", "b", Window_Utility), GB_PROPERTY("Border", "b", CWINDOW_border), GB_PROPERTY("Resizable", "b", CWINDOW_resizable), GB_PROPERTY_READ("Screen", "i", Window_Screen), GB_PROPERTY_SELF("Menus", ".WindowMenus"), GB_PROPERTY_SELF("Controls", ".WindowControls"), WINDOW_DESCRIPTION, GB_EVENT("Close", "b", NULL, &EVENT_Close), GB_EVENT("Open", NULL, NULL, &EVENT_Open), GB_EVENT("Activate", NULL, NULL, &EVENT_Activate), GB_EVENT("Deactivate", NULL, NULL, &EVENT_Deactivate), GB_EVENT("Move", NULL, NULL, &EVENT_Move), GB_EVENT("Resize", NULL, NULL, &EVENT_Resize), GB_EVENT("Show", NULL, NULL, &EVENT_Show), GB_EVENT("Hide", NULL, NULL, &EVENT_Hide), GB_EVENT("Title", NULL, NULL, &EVENT_Title), GB_EVENT("Icon", NULL, NULL, &EVENT_Icon), GB_INTERFACE("Draw", &DRAW_Interface), GB_END_DECLARE }; GB_DESC CWindowsDesc[] = { GB_DECLARE("Windows", 0), GB_VIRTUAL_CLASS(), GB_STATIC_METHOD("_next", "Window", CWINDOW_next, NULL), GB_STATIC_METHOD("_get", "Window", CWINDOW_get_from_id, "(Id)i"), GB_STATIC_PROPERTY_READ("Count", "i", CWINDOW_count), GB_END_DECLARE }; GB_DESC CFormDesc[] = { GB_DECLARE("Form", sizeof(CFORM)), GB_INHERITS("Window"), GB_AUTO_CREATABLE(), GB_STATIC_METHOD("Main", NULL, CFORM_main, NULL), GB_STATIC_METHOD("Load", NULL, CFORM_load, "[(Parent)Control;]"), GB_METHOD("_new", NULL, CFORM_new, NULL), FORM_DESCRIPTION, GB_END_DECLARE }; /*************************************************************************** MyMainWindow ***************************************************************************/ MyMainWindow::MyMainWindow(QWidget *parent, const char *name, bool embedded) : QWidget::QWidget(parent, embedded ? Qt::Widget : Qt::Window) { sg = 0; //shown = false; //border = BorderResizable; _border = true; _resizable = true; //state = StateNormal; mustCenter = false; _deleted = false; _type = _NET_WM_WINDOW_TYPE_NORMAL; _enterLoop = false; //setAttribute(Qt::WA_KeyCompression, true); //setAttribute(Qt::WA_InputMethodEnabled, true); setAttribute(Qt::WA_QuitOnClose, false); setAttribute(Qt::WA_StaticContents, true); setObjectName(name); setFocusPolicy(Qt::NoFocus); _activate = false; } MyMainWindow::~MyMainWindow() { CWINDOW *_object = (CWINDOW *)CWidget::get(this); #if DEBUG_WINDOW qDebug("~MyMainWindow: %s %s %p", GB.GetClassName(THIS), THIS->widget.name, THIS); #endif do_close(THIS, 0, true); if (CWINDOW_Active == THIS) CWINDOW_Active = 0; if (CWINDOW_LastActive == THIS) { CWINDOW_LastActive = 0; //qDebug("CWINDOW_LastActive = 0"); } if (sg) delete sg; GB.Detach(THIS); if (THIS->menuBar) { //CMenu::unrefChildren(THIS->menuBar); //qDebug("delete menuBar"); QMenuBar *menuBar = THIS->menuBar; THIS->menuBar = 0; delete menuBar; } CWindow::removeTopLevel(THIS); _deleted = true; //qDebug("~MyMainWindow %p (end)", this); } void MyMainWindow::showEvent(QShowEvent *e) { CWINDOW *_object = (CWINDOW *)CWidget::get(this); emit_open_event(THIS); //CWINDOW_fix_menubar(THIS); if (_activate) { //qDebug("showEvent: activate: %s", THIS->widget.name); raise(); //setFocus(); activateWindow(); //X11_window_activate(winId()); _activate = false; } } void MyMainWindow::initProperties() { #ifndef NO_X_WINDOW CWIDGET *_object = CWidget::get(this); if (!THIS->toplevel) return; CWINDOW_change_property(this, X11_atom_net_wm_state_above, THIS->stacking == 1); CWINDOW_change_property(this, X11_atom_net_wm_state_stays_on_top, THIS->stacking == 1); CWINDOW_change_property(this, X11_atom_net_wm_state_below, THIS->stacking == 2); CWINDOW_change_property(this, X11_atom_net_wm_state_skip_taskbar, THIS->skipTaskbar); X11_set_window_type(winId(), _type); #endif } void MyMainWindow::afterShow() { if (!CWIDGET_test_flag(THIS, WF_CLOSED)) { //define_mask(THIS, THIS->picture, THIS->masked); THIS->loopLevel = CWINDOW_Current ? CWINDOW_Current->loopLevel : 0; } } void MyMainWindow::activateLater() { activateWindow(); } void MyMainWindow::showActivate(QWidget *transient) { CWIDGET *_object = CWidget::get(this); QWidget *newParentWidget = 0; //qDebug("showActivate: %s %d", THIS->widget.name, isToolbar()); // Reparent the window if, for example, there is an already modal window displayed if (CWINDOW_Current && THIS != CWINDOW_Current) { newParentWidget = CWINDOW_Current->widget.widget; if (!isVisible()) { if (newParentWidget && parentWidget() != newParentWidget) { //qDebug("showActivate"); doReparent(newParentWidget, windowFlags(), pos()); } } } #ifndef NO_X_WINDOW if (isToolbar()) { if (!newParentWidget && CWINDOW_Main && THIS != CWINDOW_Main) newParentWidget = CWINDOW_Main->widget.widget; if (newParentWidget) X11_set_transient_for(winId(), newParentWidget->winId()); } #endif //qDebug("showActivate %p", _object); //CWIDGET_clear_flag(THIS, WF_CLOSED); if (!THIS->title && _border) setWindowTitle(GB.Application.Title()); initProperties(); if (!isVisible()) { //GB.Raise(THIS, EVENT_Open, 0); //X11_window_startup(WINDOW->winId(), THIS->x, THIS->y, THIS->w, THIS->h); if (isToolbar() && _resizable) { setMinimumSize(THIS->minw, THIS->minh); setSizeGrip(true); } else setSizeGrip(false); if (windowState() & Qt::WindowMinimized) showMinimized(); else if (windowState() & Qt::WindowFullScreen) showFullScreen(); else if (windowState() & Qt::WindowMaximized) showMaximized(); else show(); /*if (_type == _NET_WM_WINDOW_TYPE_NORMAL || _type == _NET_WM_WINDOW_TYPE_DOCK || _type == _NET_WM_WINDOW_TYPE_TOOLBAR || _type == _NET_WM_WINDOW_TYPE_MENU || _type == _NET_WM_WINDOW_TYPE_UTILITY || _type == _NET_WM_WINDOW_TYPE_DIALOG || _type == _NET_WM_WINDOW_TYPE_DROPDOWN_MENU || _type == _NET_WM_WINDOW_TYPE_POPUP_MENU || _type == _NET_WM_WINDOW_TYPE_COMBO) {*/ if (hasBorder()) { //MAIN_process_events(); //usleep(50000); //_activate = TRUE; //if (isToolbar()) QTimer::singleShot(50, this, SLOT(activateLater())); //else // activateWindow(); } } else { //_activate = true; if (windowState() & Qt::WindowMinimized) { setWindowState(windowState() & ~Qt::WindowMinimized); //qDebug("_activate set #2"); } raise(); if (hasBorder()) activateWindow(); } afterShow(); } void MyMainWindow::showModal(void) { Qt::WindowFlags flags = windowFlags(); CWIDGET *_object = CWidget::get(this); bool persistent = CWIDGET_test_flag(THIS, WF_PERSISTENT); CWINDOW *save = CWINDOW_Current; QPoint p = pos(); QEventLoop *old; QEventLoop eventLoop; if (isModal()) return; old = MyApplication::eventLoop; MyApplication::eventLoop = &eventLoop; mustCenter = true; #ifndef NO_X_WINDOW if (CWINDOW_Active) X11_set_transient_for(winId(), CWINDOW_Active->widget.widget->winId()); #endif setWindowModality(Qt::ApplicationModal); if (_resizable && _border) { setMinimumSize(THIS->minw, THIS->minh); setSizeGrip(true); } _enterLoop = false; // Do not call exitLoop() if we do not entered the loop yet! show(); afterShow(); THIS->loopLevel++; CWINDOW_Current = THIS; _enterLoop = true; eventLoop.exec(); //eventLoop.processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); MyApplication::eventLoop = old; CWINDOW_Current = save; if (persistent) { setSizeGrip(false); setWindowModality(Qt::NonModal); } CWINDOW_ensure_active_window(); } void MyMainWindow::showPopup(QPoint &pos) { Qt::WindowFlags flags = windowFlags(); CWIDGET *_object = CWidget::get(this); bool persistent = CWIDGET_test_flag(THIS, WF_PERSISTENT); CWINDOW *save = CWINDOW_Current; if (isModal()) return; setWindowFlags(Qt::Popup); setWindowModality(Qt::ApplicationModal); /*if (_resizable && _border) { setMinimumSize(THIS->minw, THIS->minh); setSizeGrip(true); }*/ _enterLoop = false; // Do not call exitLoop() if we do not entered the loop yet! move(0, 0); move(pos); show(); raise(); if (THIS->focus) handle_focus(THIS); else setFocus(); afterShow(); //QTimer::singleShot(50, this, SLOT(activateLater())); THIS->loopLevel++; CWINDOW_Current = THIS; //handle_focus(THIS); //activateWindow(); _enterLoop = true; QEventLoop eventLoop; QEventLoop *old; old = MyApplication::eventLoop; MyApplication::eventLoop = &eventLoop; eventLoop.exec(); MyApplication::eventLoop = old; //eventLoop.exec(); //eventLoop.processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::DeferredDeletion, 0); CWINDOW_Current = save; if (persistent) { setWindowModality(Qt::NonModal); setWindowFlags(Qt::Window); } CWIDGET_check_hovered(); } bool MyMainWindow::isToolbar(void) { #ifdef NO_X_WINDOW return false; #else return getType() == _NET_WM_WINDOW_TYPE_UTILITY; #endif } #if 0 void MyMainWindow::setTool(bool t) { WFlags f = getWFlags(); if (t) f |= WStyle_Tool | WStyle_Customize; else f &= ~WStyle_Tool; doReparent(CWINDOW_Main ? (MyMainWindow *)QWIDGET(CWINDOW_Main) : 0, f, pos()); } #endif void MyMainWindow::moveSizeGrip() { CWINDOW *window; QWidget *cont; if (sg == 0) return; window = (CWINDOW *)CWidget::get(this); cont = window->container; if (qApp->isRightToLeft()) sg->move(cont->rect().bottomLeft() - sg->rect().bottomLeft()); else sg->move(cont->rect().bottomRight() - sg->rect().bottomRight()); } void MyMainWindow::setSizeGrip(bool on) { if (on == (sg != 0)) return; if (!on) { delete sg; sg = 0; } else //if (!parentWidget()) { sg = new QSizeGrip(((CWINDOW *)CWidget::get(this))->container); sg->adjustSize(); moveSizeGrip(); sg->lower(); //if (paletteBackgroundPixmap()) // sg->setBackgroundOrigin(QWidget::AncestorOrigin); sg->show(); } } void MyMainWindow::setBorder(bool b, bool force) { Qt::WindowFlags flags; if (_border == b && !force) return; _border = b; flags = windowFlags(); if (b) flags &= ~(Qt::FramelessWindowHint); //|Qt::ToolTip); else flags |= Qt::FramelessWindowHint; //|Qt::ToolTip; doReparent(parentWidget(), flags, pos()); } void MyMainWindow::setResizable(bool b, bool force) { if (_resizable == b && !force) return; _resizable = b; if (!b && isWindow()) { setMinimumSize(width(), height()); setMaximumSize(width(), height()); } else { setMinimumSize(0, 0); setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } #ifdef NO_X_WINDOW #else int MyMainWindow::getType() { if (!isWindow()) return 0; else return _type; //return X11_get_window_type(winId()); } void MyMainWindow::setType(int type) { if (!isWindow()) return; X11_set_window_type(winId(), type); _type = type; } #endif void MyMainWindow::paintUnclip(bool on) { setAttribute(Qt::WA_PaintUnclipped, on); } void MyMainWindow::moveEvent(QMoveEvent *e) { CWIDGET *_object = CWidget::getReal(this); //qDebug("Move: (%s %p) %d %d", GB.GetClassName(THIS), THIS, e->pos().x(), e->pos().y()); QWidget::moveEvent(e); //qDebug("Move (pos %d %d) (oldPos %d %d)", e->pos().x(), e->pos().y(), e->oldPos().x(), e->oldPos().y()); //qDebug(" (geom %d %d) (fgeom %d %d)", geometry().x(), geometry().y(), frameGeometry().x(), frameGeometry().y()); //qDebug(" Visible = %s Hidden = %s", (isVisible() ? "Yes" : "No"), (isHidden() ? "Yes" : "No")); //qDebug(" Flags = 0x%s State = 0x%s", QString::number(getWFlags(), 16).latin1(), QString::number(getWState(), 16).latin1()); //if (CWIDGET_test_flag(ob, WF_IGNORE_MOVE)) //if (THIS->embedded) // return; if (THIS->toplevel) { if (hasBorder() && !THIS->reallyMasked) if (geometry().x() == frameGeometry().x() && geometry().y() == frameGeometry().y()) return; if (!isHidden()) { THIS->x = x(); THIS->y = y(); //qDebug("moveEvent: x= %d y = %d", x(), y()); } } //qDebug("moveEvent %ld %ld isHidden:%s shown:%s ", THIS->x, THIS->y, isHidden() ? "1" : "0", shown ? "1" : "0"); if (THIS->opened) GB.Raise(THIS, EVENT_Move, 0); } /* static void post_resize_event(CWINDOW *_object) { qDebug("post resize: %d %d", THIS->w, THIS->h); WINDOW->resize(THIS->w, THIS->h); GB.Unref(POINTER(&_object)); } */ void MyMainWindow::resizeEvent(QResizeEvent *e) { CWINDOW *_object = (CWINDOW *)CWidget::getReal(this); //int w, h; //qDebug("Resize %p: %d %d <- %d %d", _object, e->size().width(), e->size().height(), e->oldSize().width(), e->oldSize().height()); //QMainWindow::resizeEvent(e); configure(); if (sg) moveSizeGrip(); if (!isHidden()) { THIS->w = THIS->container->width(); THIS->h = THIS->container->height(); if (isTopLevel()) CCONTAINER_arrange(THIS); } #ifndef NO_X_WINDOW if (THIS->xembed) XEMBED->resize(THIS->w, THIS->h); #endif //qDebug("resizeEvent %ld %ld isHidden:%s shown:%s ", THIS->w, THIS->h, isHidden() ? "1" : "0", shown ? "1" : "0"); //qDebug("THIS->h = %ld THIS->container->height() = %ld height() = %ld", THIS->h, THIS->container->height(), height()); if (THIS->opened) { /*w = THIS->w; h = THIS->h;*/ GB.Raise(THIS, EVENT_Resize, 0); /*if (w != THIS->w || h != THIS->h) { GB.Ref(THIS); GB.Post((void (*)())post_resize_event, (intptr_t)THIS); }*/ } } void MyMainWindow::keyPressEvent(QKeyEvent *e) { CWINDOW *_object = (CWINDOW *)CWidget::getReal(this); QPushButton *test = 0; CWIDGET *ob; bool cancel; e->ignore(); //qDebug("MyMainWindow::keyPressEvent: (%p '%s' %s)", this, this ? this->caption().latin1() : 0, GB.GetClassName(CWidget::get(this))); if (GB.CanRaise(THIS, EVENT_KeyPress)) { CKEY_clear(true); GB.FreeString(&CKEY_info.text); CKEY_info.text = GB.NewZeroString(TO_UTF8(e->text())); CKEY_info.state = e->modifiers(); CKEY_info.code = e->key(); cancel = GB.Raise(THIS, EVENT_KeyPress, 0); CKEY_clear(false); if (cancel) return; } if ((e->modifiers() == Qt::NoModifier || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter ))) { switch (e->key()) { case Qt::Key_Enter: case Qt::Key_Return: test = THIS->defaultButton; break; case Qt::Key_Escape: test = THIS->cancelButton; break; } if (!test) return; ob = CWidget::get(test); if (!ob) return; if (CWIDGET_test_flag(ob, WF_DESIGN)) return; if (!test->isVisible() || !test->isEnabled()) return; test->animateClick(); e->accept(); } } static bool closeAll() { QList list(CWindow::list); CWINDOW *win; int i; #if DEBUG_WINDOW qDebug("CLOSE ALL"); #endif for (i = 0; i < list.count(); i++) { win = list.at(i); if (win != CWINDOW_Main && do_close(win, 0)) { return true; } } return false; } static void deleteAll() { QList list(CWindow::list); CWINDOW *win; int i; #if DEBUG_WINDOW qDebug("<<< DELETE ALL"); #endif for (i = 0; i < list.count(); i++) { win = CWindow::list.at(i); if (win != CWINDOW_Main) CWIDGET_destroy((CWIDGET *)win); } #if DEBUG_WINDOW qDebug("DELETE ALL >>>"); #endif //qApp->eventLoop()->processEvents(QEventLoop::AllEvents); } void MyMainWindow::closeEvent(QCloseEvent *e) { CWINDOW *_object = (CWINDOW *)CWidget::get(this); bool cancel = false; bool modal; e->ignore(); #if DEBUG_WINDOW qDebug("closeEvent: CWINDOW_Current = %p / %d <-> %p / %d", CWINDOW_Current, CWINDOW_Current ? CWINDOW_Current->loopLevel : -1, THIS, THIS->loopLevel); #endif if (THIS->opened) { // If a window is not opened, then it can be closed whatever the loop level is if (CWINDOW_Current && (THIS->loopLevel != CWINDOW_Current->loopLevel)) { goto IGNORE; } //qDebug("THIS->opened = %d: %p: %s", THIS->opened, THIS, GB.GetClassName(THIS)); THIS->closing = true; //qDebug("Close event: %s %p", GB.GetClassName(THIS), THIS); cancel = GB.Raise(THIS, EVENT_Close, 0); THIS->closing = false; } if (!cancel && THIS == CWINDOW_Main) { if (closeAll()) cancel = true; } if (cancel) goto IGNORE; modal = isModal(); //testWFlags(Qt::WShowModal); // && THIS->opened; CWIDGET_set_flag(THIS, WF_CLOSED); //qApp->sendEvent(WIDGET, new QEvent(EVENT_CLOSE)); /*if (CWINDOW_Active == THIS) { //qDebug("closeEvent activate: %p %p", CWidget::get(WIDGET->parentWidget()), CWINDOW_Active); CWINDOW_activate(CWidget::get(WIDGET->parentWidget())); }*/ if (CWINDOW_LastActive == THIS) { //GB.Unref(POINTER(&CWINDOW_LastActive)); CWINDOW_LastActive = NULL; //qDebug("CWINDOW_LastActive = 0"); } if (THIS == CWINDOW_Active) CWINDOW_activate(NULL); if (!CWIDGET_test_flag(THIS, WF_PERSISTENT)) { if (CWINDOW_Main == THIS) { deleteAll(); #if DEBUG_WINDOW qDebug("CWINDOW_Main -> NULL"); #endif CWINDOW_Main = NULL; } CWIDGET_destroy((CWIDGET *)THIS); } e->accept(); if (isModal() && _enterLoop) MyApplication::eventLoop->exit(); #if DEBUG_WINDOW qDebug("THIS->opened <- false: %p: %s", THIS, GB.GetClassName(THIS)); #endif THIS->opened = false; return; IGNORE: CWIDGET_clear_flag(THIS, WF_CLOSED); e->ignore(); } bool MyMainWindow::isPersistent(void) { return !testAttribute(Qt::WA_DeleteOnClose); //testWFlags(WDestructiveClose); } void MyMainWindow::setPersistent(bool pers) { setAttribute(Qt::WA_DeleteOnClose, !pers); } void MyMainWindow::doReparent(QWidget *parent, Qt::WindowFlags f, const QPoint &pos) { CWINDOW *_object = (CWINDOW *)CWidget::get(this); QIcon icon; bool old_toplevel; bool hidden; #ifndef NO_X_WINDOW bool active = qApp->activeWindow() == this; #endif icon = windowIcon(); old_toplevel = THIS->toplevel; THIS->toplevel = !parent || parent->isWindow(); THIS->embedded = !THIS->toplevel; if (THIS->toplevel) { f |= Qt::Window; if (!old_toplevel) CWindow::insertTopLevel(THIS); } else { f &= ~Qt::WindowType_Mask; if (old_toplevel) { THIS->toplevel = true; CWindow::removeTopLevel(THIS); THIS->toplevel = false; } } //qDebug("doReparent: %s %p: visible = %d opened = %d hidden = %d isVisible = %d isHidden = %d shown = %d", // THIS->widget.name, THIS, THIS->widget.flag.visible, THIS->opened, THIS->hidden, isVisible(), isHidden(), THIS->widget.flag.shown); //if (!THIS->hidden) showIt = true; //hide(); hidden = THIS->hidden; //qDebug("doReparent: %s %p: hidden = %d", THIS->widget.name, THIS, hidden); setParent(parent, f); move(pos); //qDebug("doReparent: (%s %p) (%d %d) -> (%d %d)", GB.GetClassName(THIS), THIS, pos.x(), pos.y(), WIDGET->x(), WIDGET->y()); if (!THIS->embedded) { #ifndef NO_X_WINDOW initProperties(); if (active && hasBorder()) activateWindow(); #endif setWindowIcon(icon); } //qDebug("--> isVisible = %d isHidden = %d", isVisible(), isHidden()); /*if (THIS->embedded && !THIS->hidden) { qDebug("doReparent: %s %p: show_later", THIS->widget.name, THIS); #if DEBUG_WINDOW qDebug("post show_later %s %p", GB.GetClassName(THIS), THIS); #endif GB.Ref(THIS); //GB.Post((void (*)())show_later, (intptr_t)THIS); show_later(THIS); //WIDGET->show(); }*/ /*if (parentWidget()) qDebug("doReparent (%s %p): new parent = (%s %p)", THIS->widget.name, THIS, CWidget::get(parentWidget())->name, CWidget::get(parentWidget())); else qDebug("doReparent (%s %p): new parent = 0", THIS->widget.name, THIS);*/ if (!hidden) CWINDOW_show(THIS, NULL); } void MyMainWindow::center(bool force = false) { CWINDOW *_object = (CWINDOW *)CWidget::get(this); QPoint p; QRect r; if (!force && !mustCenter) return; mustCenter = false; r = QApplication::desktop()->availableGeometry(QApplication::desktop()->screenNumber(this)); CWIDGET_move(THIS, r.x() + (r.width() - width()) / 2, r.y() + (r.height() - height()) / 2); } void MyMainWindow::configure() { CWINDOW *_object = (CWINDOW *)CWidget::get(this); QMenuBar *menuBar = THIS->menuBar; //qDebug("THIS->menuBar = %p menuBar() = %p", THIS->menuBar, menuBar()); if (menuBar && THIS->showMenuBar && !THIS->hideMenuBar) { //qDebug("action.count = %d", menuBar->actions().count()); //h = menuBar->sizeHint().height(); menuBar->show(); THIS->container->setGeometry(0, menuBar->height(), this->width(), this->height() - menuBar->height()); menuBar->setGeometry(0, 0, this->width(), menuBar->height()); } else { if (menuBar) { menuBar->move(0, -menuBar->height()); menuBar->lower(); } //qDebug("configure: %s (%d %d)", GB.GetClassName(THIS), this->width(), this->height()); THIS->container->setGeometry(0, 0, this->width(), this->height()); //THIS->container->setGeometry(0, 0, THIS->w, THIS->h); THIS->container->raise(); } CCONTAINER_arrange(THIS); //qDebug(">>> THIS->menuBar = %p menuBar() = %p", THIS->menuBar, menuBar()); //qDebug("configure: %p (%d %d %d %d)", THIS, ((QFrame *)(THIS->container))->contentsRect().x(), ((QFrame *)(THIS->container))->contentsRect().y(), ((QFrame *)(THIS->container))->contentsRect().width(), ((QFrame *)(THIS->container))->contentsRect().height()); } void MyMainWindow::setName(const char *name, CWIDGET *control) { if (_deleted) return; names.remove(name); if (control) names.insert(name, control); } void MyMainWindow::resize(int w, int h) { bool save = _resizable; if (!_resizable) setResizable(true); QWidget::resize(w, h); if (_resizable != save) setResizable(save); } void MyMainWindow::setGeometry(int x, int y, int w, int h) { bool save = _resizable; if (!_resizable) setResizable(true); QWidget::setGeometry(x, y, w, h); if (_resizable != save) setResizable(save); } void MyMainWindow::changeEvent(QEvent *e) { QWidget::changeEvent(e); if (e->type() == QEvent::StyleChange || e->type() == QEvent::FontChange) configure(); } /*************************************************************************** CWindow ***************************************************************************/ CWindow CWindow::manager; int CWindow::count = 0; QList CWindow::list; /*static void post_activate_event(void *ob) { GB.Raise(ob, EVENT_Activate, 0); GB.Unref(&ob); } static void post_deactivate_event(void *ob) { GB.Raise(ob, EVENT_Deactivate, 0); GB.Unref(&ob); }*/ void CWINDOW_activate(CWIDGET *ob) { CWINDOW *active; //qDebug("CWINDOW_activate: %s", ob ? ob->name : "NULL"); if (ob) { active = CWidget::getWindow(ob); for(;;) { if (active->toplevel) break; if (GB.CanRaise(active, EVENT_Activate)) break; active = CWidget::getWindow(CWidget::get(QWIDGET(active)->parentWidget())); } } else active = 0; if (active == CWINDOW_Active) return; //qDebug("activate: (%s %p): (%s %p) -> (%s %p)", ob ? GB.GetClassName(ob) : "", ob, CWINDOW_Active ? GB.GetClassName(CWINDOW_Active) : "", CWINDOW_Active, active ? GB.GetClassName(active) : "", active); if (CWINDOW_Active) { GB.Raise(CWINDOW_Active, EVENT_Deactivate, 0); CWINDOW_Active = 0; } if (active) GB.Raise(active, EVENT_Activate, 0); CWINDOW_Active = active; } void CWINDOW_set_default_button(CWINDOW *win, QPushButton *button, bool on) { if (on) { if (win->defaultButton) win->defaultButton->setDefault(false); win->defaultButton = button; button->setDefault(true); } else { if (win->defaultButton == button) { button->setDefault(false); win->defaultButton = 0; } } } void CWINDOW_set_cancel_button(CWINDOW *win, QPushButton *button, bool on) { //qDebug("CWINDOW_set_cancel_button: (%s %p) (%s %p) %d", GB.GetClassName(win), win, GB.GetClassName(CWidget::get(button)), CWidget::get(button), on); if (on) { win->cancelButton = button; } else { if (button == win->cancelButton) win->cancelButton = 0; } } bool CWindow::eventFilter(QObject *o, QEvent *e) { CWINDOW *_object = (CWINDOW *)CWidget::get(o); if (THIS && !CWIDGET_test_flag(THIS, WF_DELETED)) { /*if (e->type() == QEvent::WindowActivate && e->spontaneous()) { //qDebug("Activate: fake focus"); CWIDGET_handle_focus((CWIDGET *)THIS, true); } else if (e->type() == QEvent::WindowDeactivate && e->spontaneous()) { //qDebug("Activate: fake focus"); CWIDGET_handle_focus((CWIDGET *)THIS, false); } else */ if (e->type() == QEvent::Show) // && !e->spontaneous()) { MyMainWindow *w = (MyMainWindow *)o; //qDebug("Show: %s %d (%d)", GB.GetClassName(THIS), !WINDOW->isHidden(), e->spontaneous()); if (THIS->toplevel) w->center(); //handle_focus(THIS); post_show_event(THIS); //CWINDOW_define_mask(THIS); GB.Raise(THIS, EVENT_Show, 0); if (!e->spontaneous()) CACTION_raise(THIS); } else if (e->type() == QEvent::Hide) // && !e->spontaneous()) { //qDebug("Hide: %s %d (%d)", GB.GetClassName(THIS), WINDOW->isHidden(), e->spontaneous()); //if (WINDOW->isHidden()) { GB.Raise(THIS, EVENT_Hide, 0); if (!e->spontaneous()) CACTION_raise(THIS); } } } return QObject::eventFilter(o, e); // standard event processing } void CWindow::error(void) { //CWINDOW *_object = (CWINDOW *)CWidget::getReal((QObject *)sender()); //qDebug("XEMBED: CWindow::error %p -> %p", sender(), THIS); CWINDOW_EmbedState = EMBED_ERROR; } void CWindow::embedded(void) { //CWINDOW *_object = (CWINDOW *)CWidget::getReal((QObject *)sender()); //qDebug("XEMBED: CWindow::embedded %p -> %p", sender(), THIS); CWINDOW_EmbedState = EMBED_OK; } void CWindow::closed(void) { //CWINDOW *_object = (CWINDOW *)CWidget::getReal((QObject *)sender()); //qDebug("XEMBED: CWindow::closed %p -> %p", sender(), THIS); //CWIDGET_destroy(CWidget::getReal((QObject *)sender())); delete sender(); } void CWindow::destroy(void) { CWINDOW *_object = (CWINDOW *)CWidget::getReal((QObject *)sender()); //qDebug("XEMBED: CWindow::destroy %p -> %p", sender(), THIS); if (THIS) { do_close(THIS, 0, true); CWindow::removeTopLevel(THIS); } CWINDOW_EmbedState = EMBED_WAIT; CWINDOW_Embedded = false; CWINDOW_Embedder = 0; } void CWindow::insertTopLevel(CWINDOW *_object) { if (!THIS->toplevel) return; list.append(THIS); count = list.count(); #if DEBUG_WINDOW qDebug("insertTopLevel: count = %d (%p %s %s)", count, _object, THIS->widget.name, THIS->embedded ? "E" : "W"); #endif } void CWindow::removeTopLevel(CWINDOW *_object) { if (!THIS->toplevel) return; list.removeAll(THIS); count = list.count(); #if DEBUG_WINDOW qDebug("removeTopLevel: count = %d (%p %s %s)", count, THIS, THIS->widget.name, THIS->embedded ? "E" : "W"); #endif MAIN_check_quit(); } CMENU *CWindow::findMenu(CWINDOW *_object, const char *name) { int i; CMENU *menu; if (THIS->menuBar) { for (i = 0; i < THIS->menuBar->actions().count(); i++) { menu = CMenu::dict[THIS->menuBar->actions().at(i)]; if (menu && !strcasecmp(menu->widget.name, name)) return menu; } } return NULL; }