/*
* resize_sp.cc
*
* Copyright (C) 1995-2001 Kenichi Kourai
*
* 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 qvwm; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include "main.h"
#include "misc.h"
#include "qvwm.h"
#include "event.h"
#include "taskbar.h"
#include "fbutton.h"
#include "tbutton.h"
#include "qvwmrc.h"
#include "paging.h"
#include "pager.h"
#include "mini.h"
#include "desktop.h"
#include "gnome.h"
/*
* MaximizeWindow --
* Maximize the window.
*/
void Qvwm::MaximizeWindow(Bool motion, Bool mapTransient)
{
Window junkRoot;
unsigned int junkBW, junkDepth;
Rect rcSrc, rcDest, rect;
if (this == rootQvwm)
return;
if (CheckStatus(MAXIMIZE_WINDOW))
return;
XGrabServer(display);
XGetGeometry(display, frame, &junkRoot, &rcSrc.x, &rcSrc.y,
(unsigned int *)&rcSrc.width, (unsigned int *)&rcSrc.height,
&junkBW, &junkDepth);
ASSERT(paging);
if (CheckStatus(MINIMIZE_WINDOW)) {
/*
* min -> max
*/
SetStateProperty(NormalState);
if (UseTaskbar) {
ASSERT(tButton);
rcSrc = tButton->GetRect();
rect = taskBar->GetRect();
rcSrc.x += rect.x;
rcSrc.y += rect.y;
}
}
else {
/*
* normal -> max
*/
rcSrc = rc;
rcSrc.x -= paging->origin.x;
rcSrc.y -= paging->origin.y;
flagsBak = flags;
// XXX
for (int i = 0; i < 4; i++) {
XUnmapWindow(display, side[i]);
XUnmapWindow(display, corner[i]);
}
}
ResetFlags(BORDER);
rcDest = GetFixSize(rcScreen, hints.max_width, hints.max_height,
hints.width_inc, hints.height_inc,
hints.base_width, hints.base_height);
rc = rcDest;
rc.x += paging->origin.x;
rc.y += paging->origin.y;
rcOrigBak = rcOrig;
SetStatus(MAXIMIZE_WINDOW);
ResetStatus(MINIMIZE_WINDOW);
if (UseTaskbar && motion) {
PlaySound(MaximizeSound);
MotionTitlebar(rcSrc, rcDest);
}
ConfigureNewRect(rc);
if (CheckFlags(THIN_BORDER))
XSetWindowBorderWidth(display, frame, 0);
RedrawWindow();
MapWindows(mapTransient);
SetFocus();
Gnome::SetState(this, WIN_STATE_MAXIMIZED_VERT | WIN_STATE_MAXIMIZED_HORIZ);
XUngrabServer(display);
}
/*
* MinimizeWindow --
* Minimize the window.
*/
void Qvwm::MinimizeWindow(Bool motion, Bool unmapTransient)
{
Rect rcSrc, rcDest, rect;
if (this == rootQvwm)
return;
if (CheckStatus(MINIMIZE_WINDOW))
return;
// cannot minimize without taskbar button
if (CheckFlags(NO_TBUTTON))
return;
XGrabServer(display);
if (CheckStatus(MAXIMIZE_WINDOW)) {
/*
* max->min
*/
rcSrc = GetFixSize(rcScreen, hints.max_width, hints.max_height,
hints.width_inc, hints.height_inc,
hints.base_width, hints.base_height);
}
else {
ASSERT(paging);
/*
* normal->min
*/
rcSrc = rc;
rcSrc.x -= paging->origin.x;
rcSrc.y -= paging->origin.y;
flagsBak = flags;
}
if (UseTaskbar) {
ASSERT(tButton);
rcDest = tButton->GetRect();
rect = taskBar->GetRect();
rcDest.x += rect.x;
rcDest.y += rect.y;
}
SetStatus(MINIMIZE_WINDOW);
SetStateProperty(IconicState);
if (UseTaskbar && motion) {
PlaySound(MinimizeSound);
MotionTitlebar(rcSrc, rcDest);
}
YieldFocus();
UnmapWindows(unmapTransient);
if (!ClickToFocus)
desktop.ChangeFocusToCursor();
Gnome::SetState(this, WIN_STATE_MINIMIZED);
// dummy use of an icon window spcified by application (for Tgif)
if (wmHints && (wmHints->flags & IconWindowHint) &&
wmHints->icon_window != None) {
Rect rcRoot = rootQvwm->GetRect();
XMoveWindow(display, wmHints->icon_window, rcRoot.width, rcRoot.height);
XMapWindow(display, wmHints->icon_window);
}
XUngrabServer(display);
}
/*
* RestoreWindow --
* Restore the window to previous state.
*/
void Qvwm::RestoreWindow(Bool motion, Bool mapTransient)
{
Rect rcSrc, rcDest, rect;
if (this == rootQvwm)
return;
if (!CheckStatus(MAXIMIZE_WINDOW | MINIMIZE_WINDOW))
return;
XGrabServer(display);
if (CheckStatus(MINIMIZE_WINDOW)) {
// unmap dummy icon window (for Tgif)
if (wmHints && (wmHints->flags & IconWindowHint) &&
wmHints->icon_window != None)
XUnmapWindow(display, wmHints->icon_window);
}
ASSERT(paging);
if (CheckStatus(MINIMIZE_WINDOW) && CheckStatus(MAXIMIZE_WINDOW)) {
/*
* min -> max
*/
ResetStatus(MINIMIZE_WINDOW);
SetStateProperty(NormalState);
if (UseTaskbar) {
ASSERT(tButton);
rcSrc = tButton->GetRect();
rect = taskBar->GetRect();
rcSrc.x += rect.x;
rcSrc.y += rect.y;
}
rcDest = GetFixSize(rcScreen, hints.max_width, hints.max_height,
hints.width_inc, hints.height_inc,
hints.base_width, hints.base_height);
rc = rcDest;
rc.x += paging->origin.x;
rc.y += paging->origin.y;
ResetFlags(BORDER);
if (UseTaskbar && motion) {
PlaySound(RestoreUpSound);
MotionTitlebar(rcSrc, rcDest);
}
}
else if (CheckStatus(MINIMIZE_WINDOW)) {
/*
* min -> normal
*/
ResetStatus(MAXIMIZE_WINDOW | MINIMIZE_WINDOW);
SetStateProperty(NormalState);
if (UseTaskbar) {
ASSERT(tButton);
rcSrc = tButton->GetRect();
rect = taskBar->GetRect();
rcSrc.x += rect.x;
rcSrc.y += rect.y;
}
flags = flagsBak;
CalcWindowPos(rcOrig);
rcDest = rc;
rcDest.x -= paging->origin.x;
rcDest.y -= paging->origin.y;
if (UseTaskbar && motion) {
PlaySound(RestoreUpSound);
MotionTitlebar(rcSrc, rcDest);
}
}
else if (CheckStatus(MAXIMIZE_WINDOW)) {
/*
* max -> normal
*/
ResetStatus(MAXIMIZE_WINDOW | MINIMIZE_WINDOW);
rcSrc = GetFixSize(rcScreen, hints.max_width, hints.max_height,
hints.width_inc, hints.height_inc,
hints.base_width, hints.base_height);
flags = flagsBak;
rcOrig = rcOrigBak;
CalcWindowPos(rcOrig);
rcDest = rc;
rcDest.x -= paging->origin.x;
rcDest.y -= paging->origin.y;
// XXX
for (int i = 0; i < 4; i++) {
XMapWindow(display, side[i]);
XMapWindow(display, corner[i]);
}
if (UseTaskbar && motion) {
PlaySound(RestoreDownSound);
MotionTitlebar(rcSrc, rcDest);
}
}
ConfigureNewRect(rc);
if (CheckFlags(THIN_BORDER))
XSetWindowBorderWidth(display, frame, 1);
RedrawWindow();
MapWindows(mapTransient);
SetFocus();
AdjustPage();
Gnome::ResetState(this, WIN_STATE_MAXIMIZED_VERT | WIN_STATE_MAXIMIZED_HORIZ
| WIN_STATE_MINIMIZED);
XUngrabServer(display);
}
/*
* ExpandWindow --
* Maximize the window without obscuring windows that aren't already
* obscured.
*/
void Qvwm::ExpandWindow(int dir, Bool motion)
{
if (this == rootQvwm)
return;
RectPt rpScr(paging->origin.x + rcScreen.x,
paging->origin.y + rcScreen.y,
paging->origin.x + rcScreen.x + rcScreen.width - 1,
paging->origin.y + rcScreen.y + rcScreen.height - 1);
if (!Intersect(rc, Rect(rpScr)))
return;
XGrabServer(display);
ASSERT(paging);
Rect rcOld = rc, rect;
RectPt rpOrig = (RectPt)rc;
RectPt rpNew((dir & EXPAND_LEFT) ? rpScr.left : rc.x,
(dir & EXPAND_UP) ? rpScr.top : rc.y,
(dir & EXPAND_RIGHT) ? rpScr.right : rc.x + rc.width - 1,
(dir & EXPAND_DOWN) ? rpScr.bottom : rc.y + rc.height - 1);
List<Qvwm>::Iterator i(&desktop.GetQvwmList());
// check for all windows
for (Qvwm* qvWm = i.GetHead(); qvWm; qvWm = i.GetNext()) {
if (qvWm->CheckStatus(MINIMIZE_WINDOW) || !qvWm->CheckMapped())
continue;
FixExpandedShape(dir, (RectPt)qvWm->GetRect(), rpOrig, rpNew);
}
// check for taskbar
if (UseTaskbar) {
rect = taskBar->GetRect();
rect.x += paging->origin.x;
rect.y += paging->origin.y;
FixExpandedShape(dir, (RectPt)rect, rpOrig, rpNew);
}
// check for pager
if (UsePager) {
rect = pager->GetRect();
rect.x += paging->origin.x;
rect.y += paging->origin.y;
FixExpandedShape(dir, (RectPt)rect, rpOrig, rpNew);
}
rc = GetFixSize((Rect)rpNew, hints.max_width, hints.max_height,
hints.width_inc, hints.height_inc,
hints.base_width, hints.base_height);
if (UseTaskbar && motion) {
PlaySound(ExpandSound);
MotionTitlebar(rcOld, rc);
}
ConfigureNewRect(rc);
RedrawWindow();
MapWindows(True);
SetFocus();
XUngrabServer(display);
}
/*
* Calculate new rpNew from rcTest and rpOrig.
*/
void Qvwm::FixExpandedShape(int directions, const RectPt& rpTest,
const RectPt& rpOrig, RectPt& rpNew)
{
if (directions & EXPAND_LEFT)
if (rpTest.right <= rpOrig.left && rpTest.bottom > rpOrig.top &&
rpTest.top < rpOrig.bottom)
rpNew.left = Max(rpNew.left, rpTest.right + 1);
if (directions & EXPAND_RIGHT)
if (rpOrig.right <= rpTest.left && rpTest.bottom > rpOrig.top &&
rpTest.top < rpOrig.bottom)
rpNew.right = Min(rpNew.right, rpTest.left + 1);
if (directions & EXPAND_UP)
if (rpTest.bottom <= rpOrig.top && rpTest.right > rpOrig.left &&
rpTest.left < rpOrig.right)
rpNew.top = Max(rpNew.top, rpTest.bottom + 1);
if (directions & EXPAND_DOWN)
if (rpOrig.bottom <= rpTest.top && rpTest.right > rpOrig.left &&
rpTest.left < rpOrig.right)
rpNew.bottom = Min(rpNew.bottom, rpTest.top + 1);
}
syntax highlighted by Code2HTML, v. 0.9.1