void Window::updateWindowInfoList() { KWinModule kwinModule; typedef QValueList<WId> WIdList; const WIdList & list = kwinModule.windows(); WIdList::ConstIterator it = list.begin(), end = list.end(); mWindowInfoList.clear(); for (; it!=end; ++it) { KWin::WindowInfo info = KWin::windowInfo(*it); NET::WindowType type = info.windowType(NET::AllTypesMask); if (type != NET::Desktop && type != NET::Dock && type != NET::Menu) { mWindowInfoList << info; } } }
void EntryDlg::slotDockVertical() { if (!docked) { oldMainPos = mainwin->pos(); oldMainSize = mainwin->size(); docked = true; } KWinModule info; QRect rect = info.workArea(); int diff_x = frameGeometry().width()-width(); int diff_y = frameGeometry().height()-height(); resize(minimumWidth(), rect.height()-diff_y); mainwin->resize(rect.width()-frameGeometry().width()-diff_x, rect.height()-diff_y); move (0, 0); mainwin->move(frameGeometry().width(), 0); }
// called when left-clicking the tray icon // if the window is not the active one, show it if needed, and activate it // (just like taskbar); otherwise hide it void KSystemTray::activateOrHide() { QWidget *pw = parentWidget(); if(!pw) return; #ifdef Q_WS_X11 KWin::WindowInfo info1 = KWin::windowInfo(pw->winId(), NET::XAWMState | NET::WMState); // mapped = visible (but possibly obscured) bool mapped = (info1.mappingState() == NET::Visible) && !info1.isMinimized(); // - not mapped -> show, raise, focus // - mapped // - obscured -> raise, focus // - not obscured -> hide if(!mapped) minimizeRestore(true); else { KWinModule module; for(QValueList< WId >::ConstIterator it = module.stackingOrder().fromLast(); it != module.stackingOrder().end() && (*it) != pw->winId(); --it) { KWin::WindowInfo info2 = KWin::windowInfo(*it, NET::WMGeometry | NET::XAWMState | NET::WMState | NET::WMWindowType); if(info2.mappingState() != NET::Visible) continue; // not visible on current desktop -> ignore if(!info2.geometry().intersects(pw->geometry())) continue; // not obscuring the window -> ignore if(!info1.hasState(NET::KeepAbove) && info2.hasState(NET::KeepAbove)) continue; // obscured by window kept above -> ignore NET::WindowType type = info2.windowType(NET::NormalMask | NET::DesktopMask | NET::DockMask | NET::ToolbarMask | NET::MenuMask | NET::DialogMask | NET::OverrideMask | NET::TopMenuMask | NET::UtilityMask | NET::SplashMask); if(type == NET::Dock || type == NET::TopMenu) continue; // obscured by dock or topmenu -> ignore pw->raise(); KWin::activateWindow(pw->winId()); return; } minimizeRestore(false); // hide } #endif }
void KSMServer::performLegacySessionSave() { kdDebug( 1218 ) << "Saving legacy session apps" << endl; // Setup error handler legacyWindows.clear(); windowMapPtr = &legacyWindows; XErrorHandler oldHandler = XSetErrorHandler(winsErrorHandler); // Compute set of leader windows that need legacy session management // and determine which style (WM_COMMAND or WM_SAVE_YOURSELF) KWinModule module; if( wm_save_yourself == (Atom)None ) { Atom atoms[ 3 ]; const char* const names[] = { "WM_SAVE_YOURSELF", "WM_PROTOCOLS", "WM_CLIENT_LEADER" }; XInternAtoms( tqt_xdisplay(), const_cast< char** >( names ), 3, False, atoms ); wm_save_yourself = atoms[ 0 ]; wm_protocols = atoms[ 1 ]; wm_client_leader = atoms[ 2 ]; } for ( TQValueList<WId>::ConstIterator it = module.windows().begin(); it != module.windows().end(); ++it) { WId leader = windowWmClientLeader( *it ); if (!legacyWindows.contains(leader) && windowSessionId( *it, leader ).isEmpty()) { SMType wtype = SM_WMCOMMAND; int nprotocols = 0; Atom *protocols = 0; if( XGetWMProtocols(tqt_xdisplay(), leader, &protocols, &nprotocols)) { for (int i=0; i<nprotocols; i++) if (protocols[i] == wm_save_yourself) { wtype = SM_WMSAVEYOURSELF; break; } XFree((void*) protocols); } SMData data; data.type = wtype; XClassHint classHint; if( XGetClassHint( tqt_xdisplay(), leader, &classHint ) ) { data.wmclass1 = classHint.res_name; data.wmclass2 = classHint.res_class; XFree( classHint.res_name ); XFree( classHint.res_class ); } legacyWindows.insert(leader, data); } } // Open fresh display for sending WM_SAVE_YOURSELF XSync(tqt_xdisplay(), False); Display *newdisplay = XOpenDisplay(DisplayString(tqt_xdisplay())); if (!newdisplay) { windowMapPtr = NULL; XSetErrorHandler(oldHandler); return; } WId root = DefaultRootWindow(newdisplay); XGrabKeyboard(newdisplay, root, False, GrabModeAsync, GrabModeAsync, CurrentTime); XGrabPointer(newdisplay, root, False, Button1Mask|Button2Mask|Button3Mask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); // Send WM_SAVE_YOURSELF messages XEvent ev; int awaiting_replies = 0; for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { if ( (*it).type == SM_WMSAVEYOURSELF ) { WId w = it.key(); awaiting_replies += 1; memset(&ev, 0, sizeof(ev)); ev.xclient.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = wm_protocols; ev.xclient.format = 32; ev.xclient.data.l[0] = wm_save_yourself; ev.xclient.data.l[1] = GET_QT_X_TIME(); XSelectInput(newdisplay, w, PropertyChangeMask|StructureNotifyMask); XSendEvent(newdisplay, w, False, 0, &ev); } } // Wait for change in WM_COMMAND with timeout XFlush(newdisplay); TQTime start = TQTime::currentTime(); while (awaiting_replies > 0) { if (XPending(newdisplay)) { /* Process pending event */ XNextEvent(newdisplay, &ev); if ( ( ev.xany.type == UnmapNotify ) || ( ev.xany.type == PropertyNotify && ev.xproperty.atom == XA_WM_COMMAND ) ) { WindowMap::Iterator it = legacyWindows.find( ev.xany.window ); if ( it != legacyWindows.end() && (*it).type != SM_WMCOMMAND ) { awaiting_replies -= 1; if ( (*it).type != SM_ERROR ) (*it).type = SM_WMCOMMAND; } } } else { /* Check timeout */ int msecs = start.elapsed(); if (msecs >= WM_SAVE_YOURSELF_TIMEOUT) break; /* Wait for more events */ fd_set fds; FD_ZERO(&fds); int fd = ConnectionNumber(newdisplay); FD_SET(fd, &fds); struct timeval tmwait; tmwait.tv_sec = (WM_SAVE_YOURSELF_TIMEOUT - msecs) / 1000; tmwait.tv_usec = ((WM_SAVE_YOURSELF_TIMEOUT - msecs) % 1000) * 1000; ::select(fd+1, &fds, NULL, &fds, &tmwait); } } // Terminate work in new display XAllowEvents(newdisplay, ReplayPointer, CurrentTime); XAllowEvents(newdisplay, ReplayKeyboard, CurrentTime); XSync(newdisplay, False); XCloseDisplay(newdisplay); // Restore old error handler XSync(tqt_xdisplay(), False); XSetErrorHandler(oldHandler); for (WindowMap::Iterator it = legacyWindows.begin(); it != legacyWindows.end(); ++it) { if ( (*it).type != SM_ERROR) { WId w = it.key(); (*it).wmCommand = windowWmCommand(w); (*it).wmClientMachine = windowWmClientMachine(w); } } kdDebug( 1218 ) << "Done saving " << legacyWindows.count() << " legacy session apps" << endl; }