icewm/src/aworkspaces.cc | 149 +++++++++++++++++++++++++++++++++++++++++++--- icewm/src/aworkspaces.h | 4 + icewm/src/default.h | 10 +++ icewm/src/movesize.cc | 9 +++ icewm/src/wmframe.cc | 18 ++++++ icewm/src/wmmgr.cc | 6 ++ 6 files changed, 187 insertions(+), 9 deletions(-) diff --git a/icewm/src/aworkspaces.cc b/icewm/src/aworkspaces.cc index 5b37fce..740b476 100644 --- a/icewm/src/aworkspaces.cc +++ b/icewm/src/aworkspaces.cc @@ -11,6 +11,7 @@ #include "wmframe.h" #include "yrect.h" #include "yicon.h" +#include "wmwinlist.h" #include "intl.h" @@ -20,6 +21,7 @@ #include #include #include +#include #include "base.h" @@ -46,7 +48,26 @@ WorkspaceButton::WorkspaceButton(long ws, YWindow *parent): ObjectButton(parent, //setDND(true); } -void WorkspaceButton::handleClick(const XButtonEvent &/*up*/, int /*count*/) { +void WorkspaceButton::handleClick(const XButtonEvent &up, int /*count*/) { + switch (up.button) { +#ifdef CONFIG_WINLIST + case 2: + if (windowList) + windowList->showFocused(-1, -1); + break; +#endif +#ifdef CONFIG_WINMENU + case 3: + manager->popupWindowListMenu(this, up.x_root, up.y_root); + break; +#endif + case 4: + manager->switchToPrevWorkspace(false); + break; + case 5: + manager->switchToNextWorkspace(false); + break; + } } void WorkspaceButton::handleDNDEnter() { @@ -97,19 +118,24 @@ WorkspacesPane::WorkspacesPane(YWindow *parent): YWindow(parent) { if (fWorkspaceButton) { YResourcePaths paths("", false); - int ht = 24; + int ht = smallIconSize + 8; int leftX = 0; for (w = 0; w < workspaceCount; w++) { WorkspaceButton *wk = new WorkspaceButton(w, this); if (wk) { - ref image - (paths.loadImage("workspace/", workspaceNames[w])); - - if (image != null) - wk->setImage(image); - else - wk->setText(workspaceNames[w]); + if (pagerShowPreview) { + wk->setSize((int) roundf((float) + ht * desktop->width() / desktop->height()), ht); + } else { + ref image + (paths.loadImage("workspace/", workspaceNames[w])); + + if (image != null) + wk->setImage(image); + else + wk->setText(workspaceNames[w]); + } char * wn(newstr(my_basename(workspaceNames[w]))); char * ext(strrchr(wn, '.')); @@ -217,4 +243,109 @@ YSurface WorkspaceButton::getSurface() { #endif } +void WorkspacesPane::repaint() { + if (!pagerShowPreview) return; + + for (int w = 0; w < workspaceCount; w++) { + fWorkspaceButton[w]->repaint(); + } +} + +void WorkspaceButton::paint(Graphics &g, const YRect &/*r*/) { + if (!pagerShowPreview) { + YButton::paint(g, YRect(0,0,0,0)); + return; + } + + int x(0), y(0), w(width()), h(height()); + + if (w > 1 && h > 1) { + YSurface surface(getSurface()); + g.setColor(surface.color); + g.drawSurface(surface, x, y, w, h); + + if (pagerShowBorders) { + x += 1; y += 1; w -= 2; h -= 2; + } + + int wx, wy, ww, wh; + float sf = (float) desktop->width() / w; + + YIcon *icon; + YColor *colors[] = { + surface.color, + surface.color->brighter(), + surface.color->darker(), + getColor(), + NULL, // getColor()->brighter(), + getColor()->darker() + }; + + for (YFrameWindow *yfw = manager->bottomLayer(WinLayerBelow); + yfw && yfw->getActiveLayer() <= WinLayerDock; + yfw = yfw->prevLayer()) { + if (yfw->isHidden() || + !yfw->visibleOn(fWorkspace) || + (yfw->frameOptions() & YFrameWindow::foIgnoreWinList)) + continue; + wx = (int) roundf(yfw->x() / sf) + x; + wy = (int) roundf(yfw->y() / sf) + y; + ww = (int) roundf(yfw->width() / sf); + wh = (int) roundf(yfw->height() / sf); + if (ww < 1 || wh < 1) + continue; + if (yfw->isMaximizedVert()) { // !!! hack + wy = y; wh = h; + } + if (yfw->isMinimized()) { + if (!pagerShowMinimized) + continue; + g.setColor(colors[2]); + } else { + if (ww > 2 && wh > 2) { + if (yfw->focused()) + g.setColor(colors[1]); + else + g.setColor(colors[2]); + g.fillRect(wx+1, wy+1, ww-2, wh-2); + + if (pagerShowWindowIcons && ww > smallIconSize+1 && + wh > smallIconSize+1 && (icon = yfw->clientIcon()) && + icon->small() != null) { + g.drawImage(icon->small(), + wx + (ww-smallIconSize)/2, + wy + (wh-smallIconSize)/2); + } + } + g.setColor(colors[5]); + } + if (ww == 1 && wh == 1) + g.drawPoint(wx, wy); + else + g.drawRect(wx, wy, ww-1, wh-1); + } + + if (pagerShowBorders) { + g.setColor(surface.color); + g.draw3DRect(x-1, y-1, w+1, h+1, !isPressed()); + } + + if (pagerShowNumbers) { + ref font = getFont(); + + char label[3]; + sprintf(label, "%ld", (fWorkspace+1) % 100); + + wx = (w - font->textWidth(label)) / 2 + x; + wy = (h - font->height()) / 2 + font->ascent() + y; + + g.setFont(font); + g.setColor(colors[0]); + g.drawChars(label, 0, strlen(label), wx+1, wy+1); + g.setColor(colors[3]); + g.drawChars(label, 0, strlen(label), wx, wy); + } + } +} + #endif diff --git a/icewm/src/aworkspaces.h b/icewm/src/aworkspaces.h index 5479bd1..065a55d 100644 --- a/icewm/src/aworkspaces.h +++ b/icewm/src/aworkspaces.h @@ -22,6 +22,8 @@ public: virtual YSurface getSurface(); private: + virtual void paint(Graphics &g, const YRect &r); + static YTimer *fRaiseTimer; long fWorkspace; @@ -40,6 +42,8 @@ public: WorkspacesPane(YWindow *parent); ~WorkspacesPane(); + void repaint(); + void configure(const YRect &r, const bool resized); WorkspaceButton *workspaceButton(long n); diff --git a/icewm/src/default.h b/icewm/src/default.h index 55a5d83..a655fcb 100644 --- a/icewm/src/default.h +++ b/icewm/src/default.h @@ -55,6 +55,11 @@ XIV(bool, taskBarShowWindowIcons, true) XIV(bool, taskBarAutoHide, false) XIV(bool, taskBarFullscreenAutoShow, true) XIV(bool, taskBarWorkspacesLeft, true) +XIV(bool, pagerShowPreview, true) +XIV(bool, pagerShowWindowIcons, false) +XIV(bool, pagerShowMinimized, false) +XIV(bool, pagerShowBorders, true) +XIV(bool, pagerShowNumbers, true) XIV(bool, taskBarShowCPUStatus, true) XIV(bool, taskBarShowNetStatus, true) XIV(bool, taskBarLaunchOnSingleClick, true) @@ -274,6 +279,11 @@ cfoption icewm_preferences[] = { OBV("TaskBarShowNetStatus", &taskBarShowNetStatus, "Show network status on task bar (Linux only)"), OBV("TaskBarShowCollapseButton", &taskBarShowCollapseButton, "Show a button to collapse the taskbar"), OBV("TaskBarWorkspacesLeft", &taskBarWorkspacesLeft, "Place workspace pager on left, not right"), + OBV("PagerShowPreview", &pagerShowPreview, "Show a mini desktop preview on each workspace button"), + OBV("PagerShowWindowIcons", &pagerShowWindowIcons, "Draw window icons inside large enough preview windows on pager (if PagerShowPreview=1)"), + OBV("PagerShowMinimized", &pagerShowMinimized, "Draw even minimized windows as unfilled rectangles (if PagerShowPreview=1)"), + OBV("PagerShowBorders", &pagerShowBorders, "Draw border around workspace buttons (if PagerShowPreview=1)"), + OBV("PagerShowNumbers", &pagerShowNumbers, "Show number of workspace on workspace button (if PagerShowPreview=1)"), OBV("TaskBarLaunchOnSingleClick", &taskBarLaunchOnSingleClick, "Execute taskbar applet commands (like MailCommand, ClockCommand, ...) on single click"), #endif // OBV("WarpPointer", &warpPointer, "Move mouse when doing focusing in pointer focus mode"), diff --git a/icewm/src/movesize.cc b/icewm/src/movesize.cc index fa15075..a591bbc 100644 --- a/icewm/src/movesize.cc +++ b/icewm/src/movesize.cc @@ -18,6 +18,9 @@ #include "intl.h" +#include "wmtaskbar.h" +#include "aworkspaces.h" + #include void YFrameWindow::snapTo(int &wx, int &wy, @@ -1009,6 +1012,12 @@ void YFrameWindow::endMoveSize() { sizingWindow = 0; manager->setWorkAreaMoveWindows(false); + +#ifdef CONFIG_TASKBAR + if (taskBar && taskBar->workspacesPane()) { + taskBar->workspacesPane()->repaint(); + } +#endif } void YFrameWindow::handleBeginDrag(const XButtonEvent &down, const XMotionEvent &motion) { diff --git a/icewm/src/wmframe.cc b/icewm/src/wmframe.cc index e73ff59..4a17d89 100644 --- a/icewm/src/wmframe.cc +++ b/icewm/src/wmframe.cc @@ -29,6 +29,8 @@ #include "yrect.h" #include "yicon.h" +#include "aworkspaces.h" + #include "intl.h" static YColor *activeBorderBg = 0; @@ -323,6 +325,14 @@ YFrameWindow::~YFrameWindow() { XDestroyWindow(xapp->display(), bottomLeftCorner); XDestroyWindow(xapp->display(), bottomRightCorner); manager->updateClientList(); + +#ifdef CONFIG_TASKBAR + // update pager when unfocused windows are killed, because this + // does not call YWindowManager::updateFullscreenLayer() + if (!focused() && taskBar && taskBar->workspacesPane()) { + taskBar->workspacesPane()->repaint(); + } +#endif } void YFrameWindow::doManage(YFrameClient *clientw, bool &doActivate, bool &requestFocus) { @@ -733,6 +743,14 @@ void YFrameWindow::getNewPos(const XConfigureRequestEvent &cr, cy = cur_y; } } + +#ifdef CONFIG_TASKBAR + // update pager when windows move/resize themselves (like xmms, gmplayer, ...), + // because this does not call YFrameWindow::endMoveSize() + if (taskBar && taskBar->workspacesPane()) { + taskBar->workspacesPane()->repaint(); + } +#endif } void YFrameWindow::configureClient(const XConfigureRequestEvent &configureRequest) { diff --git a/icewm/src/wmmgr.cc b/icewm/src/wmmgr.cc index 843ec12..991c6d4 100644 --- a/icewm/src/wmmgr.cc +++ b/icewm/src/wmmgr.cc @@ -1748,6 +1748,12 @@ void YWindowManager::updateFullscreenLayer() { /// HACK !!! if (taskBar) taskBar->updateFullscreen(getFocus() && getFocus()->isFullscreen()); #endif + +#ifdef CONFIG_TASKBAR + if (taskBar && taskBar->workspacesPane()) { + taskBar->workspacesPane()->repaint(); + } +#endif } void YWindowManager::restackWindows(YFrameWindow *) {