Removing TopMenu

Since the funtionality of TopMenu did no longer work in KDE4 this feature was
removed from Workspace. Every reference to it was removed as well as commentaries
and documentation.

REVIEW: 101485
This commit is contained in:
Arthur Arlt 2011-06-24 12:19:47 +02:00
parent e38ab44ea4
commit 25654f25b8
19 changed files with 25 additions and 442 deletions

View file

@ -97,10 +97,6 @@ version 1.2
TOOLBAR - many parts in KDE still treat this as "tool" window.
- should the decoration be shown for the toolbars?
KDE extensions:
_KDE_NET_WM_WINDOW_TYPE_TOPMENU - this is used for implementing
standalone menubars for applications. Only the menubar
that is transient for the currently active window will be shown.
See KMenuBar class in libkdeui for details.
_KDE_NET_WM_WINDOW_TYPE_OVERRIDE - this seems to mean "this window
should be borderless", but it's actually used also for other
things, like fullscreen windows. The plan is to get rid of this

View file

@ -247,7 +247,6 @@ void Workspace::setActiveClient(Client* c, allowed_t)
}
pending_take_activity = NULL;
updateCurrentTopMenu();
updateToolWindows(false);
if (c)
disableGlobalShortcutsForClient(c->rules()->checkDisableGlobalShortcuts(false));
@ -359,7 +358,7 @@ void Workspace::takeActivity(Client* c, int flags, bool handled)
}
cancelDelayFocus();
}
if (!(flags & ActivityFocusForce) && (c->isTopMenu() || c->isDock() || c->isSplash()))
if (!(flags & ActivityFocusForce) && (c->isDock() || c->isSplash()))
flags &= ~ActivityFocus; // toplevel menus and dock windows don't take focus if not forced
if (c->isShade()) {
if (c->wantsInput() && (flags & ActivityFocus)) {
@ -710,9 +709,9 @@ void Client::demandAttentionKNotify()
// TODO I probably shouldn't be lazy here and do it without the macro, so that people can read it
KWIN_COMPARE_PREDICATE(SameApplicationActiveHackPredicate, Client, const Client*,
// ignore already existing splashes, toolbars, utilities, menus and topmenus,
// ignore already existing splashes, toolbars, utilities and menus,
// as the app may show those before the main window
!cl->isSplash() && !cl->isToolbar() && !cl->isTopMenu() && !cl->isUtility() && !cl->isMenu()
!cl->isSplash() && !cl->isToolbar() && !cl->isUtility() && !cl->isMenu()
&& Client::belongToSameApplication(cl, value, true) && cl != value);
Time Client::readUserTimeMapTimestamp(const KStartupInfoId* asn_id, const KStartupInfoData* asn_data,

View file

@ -2109,7 +2109,7 @@ bool Client::wantsInput() const
bool Client::isSpecialWindow() const
{
// TODO
return isDesktop() || isDock() || isSplash() || isTopMenu() || isToolbar();
return isDesktop() || isDock() || isSplash() || isToolbar();
}
/**

View file

@ -592,14 +592,14 @@ void EffectsHandlerImpl::moveWindow(EffectWindow* w, const QPoint& pos, bool sna
void EffectsHandlerImpl::windowToDesktop(EffectWindow* w, int desktop)
{
Client* cl = dynamic_cast< Client* >(static_cast<EffectWindowImpl*>(w)->window());
if (cl && !cl->isDesktop() && !cl->isDock() && !cl->isTopMenu())
if (cl && !cl->isDesktop() && !cl->isDock())
Workspace::self()->sendClientToDesktop(cl, desktop, true);
}
void EffectsHandlerImpl::windowToScreen(EffectWindow* w, int screen)
{
Client* cl = dynamic_cast< Client* >(static_cast<EffectWindowImpl*>(w)->window());
if (cl && !cl->isDesktop() && !cl->isDock() && !cl->isTopMenu())
if (cl && !cl->isDesktop() && !cl->isDock())
Workspace::self()->sendClientToScreen(cl, screen);
}
@ -1474,11 +1474,6 @@ bool EffectWindowImpl::isToolbar() const
return toplevel->isToolbar();
}
bool EffectWindowImpl::isTopMenu() const
{
return toplevel->isTopMenu();
}
bool EffectWindowImpl::isMenu() const
{
return toplevel->isMenu();

View file

@ -266,7 +266,6 @@ public:
virtual bool isDesktop() const;
virtual bool isDock() const;
virtual bool isToolbar() const;
virtual bool isTopMenu() const;
virtual bool isMenu() const;
virtual bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient'
virtual bool isSpecialWindow() const;

View file

@ -220,7 +220,7 @@ bool GlideEffect::isGlideWindow(EffectWindow* w)
if (w->hasDecoration())
return true;
if (!w->isManaged() || w->isMenu() || w->isNotification() || w->isDesktop() ||
w->isDock() || w->isSplash() || w->isTopMenu() || w->isToolbar() ||
w->isDock() || w->isSplash() || w->isToolbar() ||
w->windowClass() == "dashboard dashboard")
return false;
return true;

View file

@ -542,8 +542,6 @@ bool Client::windowEvent(XEvent* e)
fetchIconicName();
if ((dirty[ WinInfo::PROTOCOLS ] & NET::WMStrut) != 0
|| (dirty[ WinInfo::PROTOCOLS2 ] & NET::WM2ExtendedStrut) != 0) {
if (isTopMenu()) // the fallback mode of KMenuBar may alter the strut
checkWorkspacePosition(); // restore it
workspace()->updateClientArea();
}
if ((dirty[ WinInfo::PROTOCOLS ] & NET::WMIcon) != 0)
@ -696,8 +694,6 @@ bool Client::mapRequestEvent(XMapRequestEvent* e)
return false;
return true; // no messing with frame etc.
}
if (isTopMenu() && workspace()->managingTopMenus())
return true; // kwin controls these
// also copied in clientMessage()
if (isMinimized())
unminimize();
@ -747,8 +743,6 @@ void Client::clientMessageEvent(XClientMessageEvent* e)
return; // ignore frame/wrapper
// WM_STATE
if (e->message_type == atoms->kde_wm_change_state) {
if (isTopMenu() && workspace()->managingTopMenus())
return; // kwin controls these
bool avoid_animation = (e->data.l[ 1 ]);
if (e->data.l[ 0 ] == IconicState)
minimize();
@ -766,8 +760,6 @@ void Client::clientMessageEvent(XClientMessageEvent* e)
}
}
} else if (e->message_type == atoms->wm_change_state) {
if (isTopMenu() && workspace()->managingTopMenus())
return; // kwin controls these
if (e->data.l[0] == IconicState)
minimize();
return;
@ -790,8 +782,7 @@ void Client::configureRequestEvent(XConfigureRequestEvent* e)
sendSyntheticConfigureNotify();
return;
}
if (isSplash() // no manipulations with splashscreens either
|| isTopMenu()) { // topmenus neither
if (isSplash()) { // no manipulations with splashscreens either
sendSyntheticConfigureNotify();
return;
}
@ -887,7 +878,7 @@ void Client::enterNotifyEvent(XCrossingEvent* e)
return;
if (options->autoRaise && !isDesktop() &&
!isDock() && !isTopMenu() && workspace()->focusChangeEnabled() &&
!isDock() && workspace()->focusChangeEnabled() &&
workspace()->topClientOnDesktop(workspace()->currentDesktop(),
options->separateScreenFocus ? screen() : -1) != this) {
delete autoRaiseTimer;
@ -898,7 +889,7 @@ void Client::enterNotifyEvent(XCrossingEvent* e)
}
QPoint currentPos(e->x_root, e->y_root);
if (options->focusPolicy != Options::FocusStrictlyUnderMouse && (isDesktop() || isDock() || isTopMenu()))
if (options->focusPolicy != Options::FocusStrictlyUnderMouse && (isDesktop() || isDock()))
return;
// for FocusFollowsMouse, change focus only if the mouse has actually been moved, not if the focus
// change came because of window changes (e.g. closing a window) - #92290

View file

@ -165,17 +165,6 @@ void Workspace::updateClientArea(bool force)
kDebug(1212) << "new_sarea: " << new_sareas[ i ][ iS ];
}
#endif
// TODO topmenu update for screenarea changes?
if (topmenu_space != NULL) {
QRect topmenu_area = desktopArea;
topmenu_area.setTop(topMenuHeight());
for (int i = 1;
i <= numberOfDesktops();
++i) {
new_wareas[ i ] = new_wareas[ i ].intersected(topmenu_area);
new_rmoveareas[ i ] += StrutRect(topmenu_area);
}
}
bool changed = force;
@ -212,7 +201,6 @@ void Workspace::updateClientArea(bool force)
rootInfo->setWorkArea(i, r);
}
updateTopMenuGeometry();
for (ClientList::ConstIterator it = clients.constBegin();
it != clients.constEnd();
++it)
@ -800,40 +788,6 @@ void Workspace::unclutterDesktop()
}
}
void Workspace::updateTopMenuGeometry(Client* c)
{
if (!managingTopMenus())
return;
if (c != NULL) {
XEvent ev;
ev.xclient.display = display();
ev.xclient.type = ClientMessage;
ev.xclient.window = c->window();
static Atom msg_type_atom = XInternAtom(display(), "_KDE_TOPMENU_MINSIZE", False);
ev.xclient.message_type = msg_type_atom;
ev.xclient.format = 32;
ev.xclient.data.l[0] = xTime();
ev.xclient.data.l[1] = topmenu_space->width();
ev.xclient.data.l[2] = topmenu_space->height();
ev.xclient.data.l[3] = 0;
ev.xclient.data.l[4] = 0;
XSendEvent(display(), c->window(), False, NoEventMask, &ev);
KWindowSystem::setStrut(c->window(), 0, 0, topmenu_height, 0); // so that kicker etc. know
c->checkWorkspacePosition();
return;
}
// c == NULL - update all, including topmenu_space
QRect area;
area = clientArea(MaximizeFullArea, QPoint(0, 0), 1); // HACK desktop ?
area.setHeight(topMenuHeight());
topmenu_space->setGeometry(area);
for (ClientList::ConstIterator it = topmenus.constBegin();
it != topmenus.constEnd();
++it)
updateTopMenuGeometry(*it);
}
// When kwin crashes, windows will not be gravitated back to their original position
// and will remain offset by the size of the decoration. So when restarting, fix this
// (the property with the size of the frame remains on the window after the crash).
@ -889,9 +843,6 @@ void Client::keepInArea(QRect area, bool partial)
QRect Client::adjustedClientArea(const QRect &desktopArea, const QRect& area) const
{
QRect r = area;
// topmenu area is reserved in updateClientArea()
if (isTopMenu())
return r;
NETExtendedStrut str = strut();
QRect stareaL = QRect(
0,
@ -1073,20 +1024,6 @@ void Client::checkWorkspacePosition()
}
if (isDock())
return;
if (isTopMenu()) {
if (workspace()->managingTopMenus()) {
QRect area;
ClientList mainclients = mainClients();
if (mainclients.count() == 1)
area = workspace()->clientArea(MaximizeFullArea, mainclients.first());
else
area = workspace()->clientArea(MaximizeFullArea, QPoint(0, 0), desktop());
area.setHeight(workspace()->topMenuHeight());
// kDebug(1212) << "TOPMENU size adjust: " << area << ":" << this;
setGeometry(area);
}
return;
}
if (maximizeMode() != MaximizeRestore)
// TODO update geom_restore?

View file

@ -383,8 +383,7 @@ void Workspace::updateMinimizedOfTransients(Client* c)
if ((*it)->isModal())
continue; // there's no reason to hide modal dialogs with the main client
// but to keep them to eg. watch progress or whatever
if (!(*it)->isMinimized()
&& !(*it)->isTopMenu()) { // topmenus are not minimized, they're hidden
if (!(*it)->isMinimized()) {
(*it)->minimize();
updateMinimizedOfTransients((*it));
}
@ -398,8 +397,7 @@ void Workspace::updateMinimizedOfTransients(Client* c)
for (ClientList::ConstIterator it = c->transients().constBegin();
it != c->transients().constEnd();
++it) {
if ((*it)->isMinimized()
&& !(*it)->isTopMenu()) {
if ((*it)->isMinimized()) {
(*it)->unminimize();
updateMinimizedOfTransients((*it));
}
@ -633,8 +631,6 @@ void Client::setTransient(Window new_transient_for_id)
transient_for->addTransient(this);
} // checkGroup() will check 'check_active_modal'
checkGroup(NULL, true); // force, because transiency has changed
if (isTopMenu())
workspace()->updateCurrentTopMenu();
workspace()->updateClientLayer(this);
workspace()->resetUpdateToolWindowsTimer();
}

View file

@ -160,32 +160,11 @@ void Workspace::propagateClients(bool propagate_new_clients)
++i)
if (electric_windows[ i ] != None)
new_stack[ pos++ ] = electric_windows[ i ];
int topmenu_space_pos = 1; // not 0, that's supportWindow !!!
for (int i = stacking_order.size() - 1; i >= 0; i--) {
if (stacking_order.at(i)->hiddenPreview())
if (stacking_order.at(i)->hiddenPreview()) {
continue;
}
new_stack[ pos++ ] = stacking_order.at(i)->frameId();
if (stacking_order.at(i)->belongsToLayer() >= DockLayer)
topmenu_space_pos = pos;
}
if (topmenu_space != NULL) {
// make sure the topmenu space is below all topmenus, fullscreens, etc.
for (int i = pos;
i > topmenu_space_pos;
--i)
new_stack[ i ] = new_stack[ i - 1 ];
new_stack[ topmenu_space_pos ] = topmenu_space->winId();
++pos;
}
// when having hidden previews, stack hidden windows below everything else
// (as far as pure X stacking order is concerned), in order to avoid having
// these windows that should be unmapped to interfere with other windows
for (int i = stacking_order.size() - 1; i >= 0; i--) {
if (!stacking_order.at(i)->hiddenPreview())
continue;
new_stack[ pos++ ] = stacking_order.at(i)->frameId();
if (stacking_order.at(i)->belongsToLayer() >= DockLayer)
topmenu_space_pos = pos;
}
// TODO isn't it too inefficient to restack always all clients?
// TODO don't restack not visible windows?
@ -309,8 +288,6 @@ void Workspace::lowerClient(Client* c, bool nogroup)
{
if (!c)
return;
if (c->isTopMenu())
return;
c->cancelAutoRaise();
@ -337,8 +314,6 @@ void Workspace::lowerClientWithinApplication(Client* c)
{
if (!c)
return;
if (c->isTopMenu())
return;
c->cancelAutoRaise();
@ -364,8 +339,6 @@ void Workspace::raiseClient(Client* c, bool nogroup)
{
if (!c)
return;
if (c->isTopMenu())
return;
c->cancelAutoRaise();
@ -393,8 +366,6 @@ void Workspace::raiseClientWithinApplication(Client* c)
{
if (!c)
return;
if (c->isTopMenu())
return;
c->cancelAutoRaise();
@ -504,8 +475,6 @@ void Workspace::restack(Client* c, Client* under)
void Workspace::restackClientUnderActive(Client* c)
{
if (c->isTopMenu())
return;
if (!active_client || active_client == c) {
raiseClient(c);
return;
@ -684,12 +653,6 @@ ClientList Workspace::ensureStackingOrder(const ClientList& list) const
// there may be some special cases where this rule shouldn't be enfored
bool Workspace::keepTransientAbove(const Client* mainwindow, const Client* transient)
{
// When topmenu's mainwindow becomes active, topmenu is raised and shown.
// They also belong to the Dock layer. This makes them to be very high.
// Therefore don't keep group transients above them, otherwise this would move
// group transients way too high.
if (mainwindow->isTopMenu() && transient->groupTransient())
return false;
// #93832 - don't keep splashscreens above dialogs
if (transient->isSplash() && mainwindow->isDialog())
return false;
@ -825,8 +788,6 @@ Layer Client::belongsToLayer() const
return BelowLayer;
if (isDock() && !keepBelow())
return DockLayer;
if (isTopMenu())
return DockLayer;
if (isActiveFullScreen())
return ActiveLayer;
if (keepAbove())

View file

@ -1135,11 +1135,6 @@ public:
* See _NET_WM_WINDOW_TYPE_TOOLBAR at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
*/
virtual bool isToolbar() const = 0;
/**
* Returns whether the window is standalone menubar (AKA macmenu).
* This window type is a KDE extension.
*/
virtual bool isTopMenu() const = 0;
/**
* Returns whether the window is a torn-off menu.
* See _NET_WM_WINDOW_TYPE_MENU at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html .

View file

@ -485,9 +485,6 @@ bool Client::manage(Window w, bool isMapped)
user_time = readUserTimeMapTimestamp(asn_valid ? &asn_id : NULL, asn_valid ? &asn_data : NULL, session);
group()->updateUserTime(user_time); // And do what Client::updateUserTime() does
if (isTopMenu()) // They're shown in Workspace::addClient() if their mainwindow
hideClient(true); // Is the active one
// This should avoid flicker, because real restacking is done
// only after manage() finishes because of blocking, but the window is shown sooner
XLowerWindow(display(), frameId());

View file

@ -254,15 +254,6 @@ unsigned long Options::updateSettings()
// and not kstyle tooltips and vise-versa, we don't read the
// "EffectNoTooltip" setting from kdeglobals.
#if 0
FIXME: we have no mac style menu implementation in kwin anymore, so this just breaks
things for people!
KConfig _globalConfig("kdeglobals");
KConfigGroup globalConfig(&_globalConfig, "KDE");
topmenus = globalConfig.readEntry("macStyle", false);
#else
topmenus = false;
#endif
// QToolTip::setGloballyEnabled( d->show_tooltips );
// KDE4 this probably needs to be done manually in clients

View file

@ -330,13 +330,6 @@ public:
return borderless_maximized_windows;
}
bool topMenuEnabled() const {
return topmenus;
}
bool desktopTopMenu() const {
return desktop_topmenu;
}
// timeout before non-responding application will be killed after attempt to close
int killPingTimeout;
@ -414,8 +407,6 @@ private:
bool electric_border_tiling;
bool borderless_maximized_windows;
bool show_geometry_tip;
bool topmenus;
bool desktop_topmenu;
// List of window classes for which not to use focus stealing prevention
QStringList ignoreFocusStealingClasses;
int animationSpeed; // 0 - instant, 5 - very slow

View file

@ -821,8 +821,6 @@ void Client::setupWindowRules(bool ignore_temporary)
{
client_rules = workspace()->findWindowRules(this, ignore_temporary);
// check only after getting the rules, because there may be a rule forcing window type
if (isTopMenu()) // TODO cannot have restrictions
client_rules = WindowRules();
}
// Applies Force, ForceTemporarily and ApplyNow rules

View file

@ -79,7 +79,6 @@ public:
bool isDesktop() const;
bool isDock() const;
bool isToolbar() const;
bool isTopMenu() const;
bool isMenu() const;
bool isNormalWindow() const; // normal as in 'NET::Normal or NET::Unknown non-transient'
bool isDialog() const;
@ -313,14 +312,9 @@ inline bool Toplevel::isDock() const
return windowType() == NET::Dock;
}
inline bool Toplevel::isTopMenu() const
{
return windowType() == NET::TopMenu;
}
inline bool Toplevel::isMenu() const
{
return windowType() == NET::Menu && !isTopMenu(); // because of backwards comp.
return windowType() == NET::Menu;
}
inline bool Toplevel::isToolbar() const

View file

@ -1191,8 +1191,7 @@ void Workspace::slotWindowToDesktop()
Client* c = active_popup_client ? active_popup_client : active_client;
if (i >= 1 && i <= numberOfDesktops() && c
&& !c->isDesktop()
&& !c->isDock()
&& !c->isTopMenu())
&& !c->isDock())
sendClientToDesktop(c, i, true);
}
@ -1216,8 +1215,7 @@ void Workspace::slotWindowToScreen()
Client* c = active_popup_client ? active_popup_client : active_client;
if (i >= 0 && i <= numScreens() && c
&& !c->isDesktop()
&& !c->isDock()
&& !c->isTopMenu()) {
&& !c->isDock()) {
sendClientToScreen(c, i);
}
}
@ -1227,8 +1225,7 @@ void Workspace::slotWindowToNextScreen()
Client* c = active_popup_client ? active_popup_client : active_client;
if (c
&& !c->isDesktop()
&& !c->isDock()
&& !c->isTopMenu()) {
&& !c->isDock()) {
sendClientToScreen(c, (c->screen() + 1) % numScreens());
}
}
@ -1380,7 +1377,7 @@ void Workspace::windowToNextDesktop(Client* c)
if (d > numberOfDesktops())
d = 1;
if (c && !c->isDesktop()
&& !c->isDock() && !c->isTopMenu()) {
&& !c->isDock()) {
setClientIsMoving(c);
setCurrentDesktop(d);
setClientIsMoving(NULL);
@ -1401,7 +1398,7 @@ void Workspace::windowToPreviousDesktop(Client* c)
if (d <= 0)
d = numberOfDesktops();
if (c && !c->isDesktop()
&& !c->isDock() && !c->isTopMenu()) {
&& !c->isDock()) {
setClientIsMoving(c);
setCurrentDesktop(d);
setClientIsMoving(NULL);
@ -1415,7 +1412,7 @@ void Workspace::slotWindowToDesktopRight()
return;
Client* c = active_popup_client ? active_popup_client : active_client;
if (c && !c->isDesktop()
&& !c->isDock() && !c->isTopMenu()) {
&& !c->isDock()) {
setClientIsMoving(c);
setCurrentDesktop(d);
setClientIsMoving(NULL);
@ -1429,7 +1426,7 @@ void Workspace::slotWindowToDesktopLeft()
return;
Client* c = active_popup_client ? active_popup_client : active_client;
if (c && !c->isDesktop()
&& !c->isDock() && !c->isTopMenu()) {
&& !c->isDock()) {
setClientIsMoving(c);
setCurrentDesktop(d);
setClientIsMoving(NULL);
@ -1443,7 +1440,7 @@ void Workspace::slotWindowToDesktopUp()
return;
Client* c = active_popup_client ? active_popup_client : active_client;
if (c && !c->isDesktop()
&& !c->isDock() && !c->isTopMenu()) {
&& !c->isDock()) {
setClientIsMoving(c);
setCurrentDesktop(d);
setClientIsMoving(NULL);
@ -1457,7 +1454,7 @@ void Workspace::slotWindowToDesktopDown()
return;
Client* c = active_popup_client ? active_popup_client : active_client;
if (c && !c->isDesktop()
&& !c->isDock() && !c->isTopMenu()) {
&& !c->isDock()) {
setClientIsMoving(c);
setCurrentDesktop(d);
setClientIsMoving(NULL);
@ -1657,8 +1654,7 @@ void Workspace::showWindowMenu(const QRect &pos, Client* cl)
if (active_popup_client != NULL) // recursion
return;
if (cl->isDesktop()
|| cl->isDock()
|| cl->isTopMenu())
|| cl->isDock())
return;
active_popup_client = cl;

View file

@ -141,11 +141,6 @@ Workspace::Workspace(bool restore)
, global_shortcuts_disabled_for_client(false)
, workspaceInit(true)
, startup(0)
, managing_topmenus(false)
, topmenu_selection(NULL)
, topmenu_watcher(NULL)
, topmenu_height(0)
, topmenu_space(NULL)
, set_active_client_recursion(0)
, block_stacking_updates(0)
, forced_global_mouse_grab(false)
@ -306,7 +301,6 @@ void Workspace::init()
NET::MenuMask |
NET::DialogMask |
NET::OverrideMask |
NET::TopMenuMask |
NET::UtilityMask |
NET::SplashMask |
// No compositing window types here unless we support them also as managed window types
@ -398,22 +392,10 @@ void Workspace::init()
if (!kapp->isSessionRestored())
++block_focus; // Because it will be set below
char nm[100];
sprintf(nm, "_KDE_TOPMENU_OWNER_S%d", DefaultScreen(display()));
Atom topmenu_atom = XInternAtom(display(), nm, False);
topmenu_selection = new KSelectionOwner(topmenu_atom);
topmenu_watcher = new KSelectionWatcher(topmenu_atom);
//TODO: grabXServer(); // Where exactly put this? topmenu selection claiming down belong must be before
{
// Begin updates blocker block
StackingUpdatesBlocker blocker(this);
if (options->topMenuEnabled() && topmenu_selection->claim(false))
setupTopMenuHandling(); // This can call updateStackingOrder()
else
lostTopMenuSelection();
unsigned int i, nwins;
Window root_return, parent_return;
Window* wins;
@ -426,8 +408,6 @@ void Workspace::init()
createUnmanaged(wins[i]);
continue;
}
if (topmenu_space && topmenu_space->winId() == wins[i])
continue;
if (attr.map_state != IsUnmapped) {
if (fixoffset)
fixPositionAfterCrash(wins[ i ], attr);
@ -519,9 +499,6 @@ Workspace::~Workspace()
delete mgr;
delete startup;
delete initPositioning;
delete topmenu_watcher;
delete topmenu_selection;
delete topmenu_space;
delete client_keys_dialog;
while (!rules.isEmpty()) {
delete rules.front();
@ -604,8 +581,6 @@ void Workspace::addClient(Client* c, allowed_t)
unconstrained_stacking_order.append(c); // Raise if it hasn't got any stacking position yet
if (!stacking_order.contains(c)) // It'll be updated later, and updateToolWindows() requires
stacking_order.append(c); // c to be in stacking_order
if (c->isTopMenu())
addTopMenu(c);
x_stacking_dirty = true;
updateClientArea(); // This cannot be in manage(), because the client got added only now
updateClientLayer(c);
@ -671,8 +646,6 @@ void Workspace::removeClient(Client* c, allowed_t)
global_focus_chain.removeAll(c);
attention_chain.removeAll(c);
showing_desktop_clients.removeAll(c);
if (c->isTopMenu())
removeTopMenu(c);
Group* group = findGroup(c->window());
if (group != NULL)
group->lostLeader();
@ -787,95 +760,6 @@ void Workspace::updateFocusChains(Client* c, FocusChainChange change)
}
}
void Workspace::updateCurrentTopMenu()
{
if (!managingTopMenus())
return;
// toplevel menubar handling
Client* menubar = 0;
bool block_desktop_menubar = false;
if (active_client) {
// Show the new menu bar first...
Client* menu_client = active_client;
for (;;) {
if (menu_client->isFullScreen())
block_desktop_menubar = true;
for (ClientList::ConstIterator it = menu_client->transients().constBegin();
it != menu_client->transients().constEnd();
++it)
if ((*it)->isTopMenu()) {
menubar = *it;
break;
}
if (menubar != NULL || !menu_client->isTransient())
break;
if (menu_client->isModal() || menu_client->transientFor() == NULL)
break; // Don't use mainwindow's menu if this is modal or group transient
menu_client = menu_client->transientFor();
}
if (!menubar) {
// Try to find any topmenu from the application (#72113)
for (ClientList::ConstIterator it = active_client->group()->members().constBegin();
it != active_client->group()->members().constEnd();
++it)
if ((*it)->isTopMenu()) {
menubar = *it;
break;
}
}
}
if (!menubar && !block_desktop_menubar && options->desktopTopMenu()) {
// Find the menubar of the desktop
Client* desktop = findDesktop(true, currentDesktop());
if (desktop != NULL) {
for (ClientList::ConstIterator it = desktop->transients().constBegin();
it != desktop->transients().constEnd();
++it)
if ((*it)->isTopMenu()) {
menubar = *it;
break;
}
}
// TODO: To be cleaned app with window grouping
// Without qt-copy patch #0009, the topmenu and desktop are not in the same group,
// thus the topmenu is not transient for it :-/.
if (menubar == NULL) {
for (ClientList::ConstIterator it = topmenus.constBegin();
it != topmenus.constEnd();
++it)
// kdesktop's topmenu has WM_TRANSIENT_FOR set pointing to the root window
// to recognize it here. Also, with the xroot hack in kdesktop, there's
// no NET::Desktop window to be transient for.
if ((*it)->wasOriginallyGroupTransient()) {
menubar = *it;
break;
}
}
}
//kDebug( 1212 ) << "CURRENT TOPMENU:" << menubar << ":" << active_client;
if (menubar) {
if (active_client && !menubar->isOnDesktop(active_client->desktop()))
menubar->setDesktop(active_client->desktop());
menubar->hideClient(false);
topmenu_space->hide();
// Make it appear like it's been raised manually - it's in the Dock layer anyway,
// and not raising it could mess up stacking order of topmenus within one application,
// and thus break raising of mainclients in raiseClient()
unconstrained_stacking_order.removeAll(menubar);
unconstrained_stacking_order.append(menubar);
} else if (!block_desktop_menubar) {
// No topmenu active - show the space window, so that there's not empty space
topmenu_space->show();
}
// ... Then hide the other ones. Avoids flickers.
for (ClientList::ConstIterator it = clients.constBegin(); it != clients.constEnd(); ++it)
if ((*it)->isTopMenu() && (*it) != menubar)
(*it)->hideClient(true);
}
void Workspace::updateToolWindows(bool also_hide)
{
// TODO: What if Client's transiency/group changes? should this be called too? (I'm paranoid, am I not?)
@ -1073,21 +957,6 @@ void Workspace::slotReconfigure()
reserveElectricBorderSwitching(true);
updateElectricBorders();
if (options->topMenuEnabled() && !managingTopMenus()) {
if (topmenu_selection->claim(false))
setupTopMenuHandling();
else
lostTopMenuSelection();
} else if (!options->topMenuEnabled() && managingTopMenus()) {
topmenu_selection->release();
lostTopMenuSelection();
}
topmenu_height = 0; // Invalidate used menu height
if (managingTopMenus()) {
updateTopMenuGeometry();
updateCurrentTopMenu();
}
if (!compositingSuspended) {
setupCompositing();
if (effects) // setupCompositing() may fail
@ -1430,8 +1299,6 @@ bool Workspace::setCurrentDesktop(int new_desktop)
else
focusToNull();
updateCurrentTopMenu();
// Update focus chain:
// If input: chain = { 1, 2, 3, 4 } and currentDesktop() = 3,
// Output: chain = { 3, 1, 2, 4 }.
@ -1556,8 +1423,6 @@ void Workspace::updateCurrentActivity(const QString &new_activity)
else
focusToNull();
updateCurrentTopMenu();
// Update focus chain:
// If input: chain = { 1, 2, 3, 4 } and currentDesktop() = 3,
// Output: chain = { 3, 1, 2, 4 }.
@ -2196,102 +2061,6 @@ bool Workspace::electricBorderEvent(XEvent* e)
return false;
}
//-----------------------------------------------------------------------------
// Top menu
void Workspace::addTopMenu(Client* c)
{
assert(c->isTopMenu());
assert(!topmenus.contains(c));
topmenus.append(c);
if (managingTopMenus()) {
int minsize = c->minSize().height();
if (minsize > topMenuHeight()) {
topmenu_height = minsize;
updateTopMenuGeometry();
}
updateTopMenuGeometry(c);
updateCurrentTopMenu();
}
//kDebug( 1212 ) << "NEW TOPMENU:" << c;
}
void Workspace::removeTopMenu(Client* c)
{
//if ( c->isTopMenu() )
// kDebug( 1212 ) << "REMOVE TOPMENU:" << c;
assert(c->isTopMenu());
assert(topmenus.contains(c));
topmenus.removeAll(c);
updateCurrentTopMenu();
// TODO: Reduce topMenuHeight() if possible?
}
void Workspace::lostTopMenuSelection()
{
//kDebug( 1212 ) << "lost TopMenu selection";
// Make sure this signal is always set when not owning the selection
disconnect(topmenu_watcher, SIGNAL(lostOwner()), this, SLOT(lostTopMenuOwner()));
connect(topmenu_watcher, SIGNAL(lostOwner()), this, SLOT(lostTopMenuOwner()));
if (!managing_topmenus)
return;
connect(topmenu_watcher, SIGNAL(lostOwner()), this, SLOT(lostTopMenuOwner()));
disconnect(topmenu_selection, SIGNAL(lostOwnership()), this, SLOT(lostTopMenuSelection()));
managing_topmenus = false;
delete topmenu_space;
topmenu_space = NULL;
updateClientArea();
for (ClientList::ConstIterator it = topmenus.constBegin();
it != topmenus.constEnd();
++it)
(*it)->checkWorkspacePosition();
}
void Workspace::lostTopMenuOwner()
{
if (!options->topMenuEnabled())
return;
//kDebug( 1212 ) << "TopMenu selection lost owner";
if (!topmenu_selection->claim(false)) {
//kDebug( 1212 ) << "Failed to claim TopMenu selection";
return;
}
//kDebug( 1212 ) << "Claimed TopMenu selection";
setupTopMenuHandling();
}
void Workspace::setupTopMenuHandling()
{
if (managing_topmenus)
return;
connect(topmenu_selection, SIGNAL(lostOwnership()), this, SLOT(lostTopMenuSelection()));
disconnect(topmenu_watcher, SIGNAL(lostOwner()), this, SLOT(lostTopMenuOwner()));
managing_topmenus = true;
topmenu_space = new QWidget(NULL, Qt::X11BypassWindowManagerHint);
Window stack[2];
stack[0] = supportWindow->winId();
stack[1] = topmenu_space->winId();
XRestackWindows(display(), stack, 2);
updateTopMenuGeometry();
topmenu_space->show();
updateClientArea();
updateCurrentTopMenu();
}
int Workspace::topMenuHeight() const
{
if (topmenu_height == 0) {
// Simply create a dummy menubar and use its preferred height as the menu height
KMenuBar tmpmenu;
tmpmenu.addAction("dummy");
topmenu_height = tmpmenu.sizeHint().height();
}
return topmenu_height;
}
KDecoration* Workspace::createDecoration(KDecorationBridge* bridge)
{
if (!hasDecorationPlugin()) {

View file

@ -512,10 +512,6 @@ public:
bool wasUserInteraction() const;
bool sessionSaving() const;
bool managingTopMenus() const;
int topMenuHeight() const;
void updateCurrentTopMenu();
int packPositionLeft(const Client* cl, int oldx, bool left_edge) const;
int packPositionRight(const Client* cl, int oldx, bool right_edge) const;
int packPositionUp(const Client* cl, int oldy, bool top_edge) const;
@ -702,8 +698,6 @@ private slots:
void configureWM();
void desktopResized();
void slotUpdateToolWindows();
void lostTopMenuSelection();
void lostTopMenuOwner();
void delayFocus();
void gotTemporaryRulesMessage(const QString&);
void cleanupTemporaryRules();
@ -787,10 +781,6 @@ private:
bool allowFullClientRaising(const Client* c, Time timestamp);
bool keepTransientAbove(const Client* mainwindow, const Client* transient);
void blockStackingUpdates(bool block);
void addTopMenu(Client* c);
void removeTopMenu(Client* c);
void setupTopMenuHandling();
void updateTopMenuGeometry(Client* c = NULL);
void updateToolWindows(bool also_hide);
void fixPositionAfterCrash(Window w, const XWindowAttributes& attr);
@ -994,13 +984,6 @@ private:
QVector<StrutRects> oldrestrictedmovearea;
QVector< QVector<QRect> > screenarea; // Array of workareas per xinerama screen for all virtual desktops
bool managing_topmenus;
KSelectionOwner* topmenu_selection;
KSelectionWatcher* topmenu_watcher;
ClientList topmenus; // Doesn't own them
mutable int topmenu_height;
QWidget* topmenu_space;
int set_active_client_recursion;
int block_stacking_updates; // When > 0, stacking updates are temporarily disabled
bool blocked_propagating_new_clients; // Propagate also new clients after enabling stacking updates?
@ -1176,11 +1159,6 @@ inline bool Workspace::wasUserInteraction() const
return was_user_interaction;
}
inline bool Workspace::managingTopMenus() const
{
return managing_topmenus;
}
inline void Workspace::sessionSaveStarted()
{
session_saving = true;