summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <Sam@XPS-SUSE.site>2009-02-21 11:17:47 +0900
committerSam Spilsbury <Sam@XPS-SUSE.site>2009-02-21 11:17:47 +0900
commit0bcc2694943cab76ab2828dc04b3c5593f35195e (patch)
tree1be7c2845965c174a6729f58ee46794dc3308599
parent29eaf8654efd723d2836382f20a4298ebacd8e7e (diff)
parent03f05201ec7251fda41224545a89284f1ce6d814 (diff)
downloadtile-0bcc2694943cab76ab2828dc04b3c5593f35195e.tar.gz
tile-0bcc2694943cab76ab2828dc04b3c5593f35195e.tar.bz2
Merge ../tile_old into compiz++
-rw-r--r--CMakeLists.txt2
-rw-r--r--Makefile36
-rw-r--r--plugin.info1
-rw-r--r--tile.c1290
-rw-r--r--tile.cpp1075
-rw-r--r--tile.h255
-rw-r--r--tile.xml.in94
7 files changed, 1402 insertions, 1351 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d9b6005..ce24058 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,3 +1,3 @@
include (CompizFusion)
-compiz_fusion_plugin (tile)
+compiz_fusion_plugin (tile PLUGINDEPS composite opengl)
diff --git a/Makefile b/Makefile
index d9a07cf..fb9d387 100644
--- a/Makefile
+++ b/Makefile
@@ -89,14 +89,14 @@ INSTALL = install
BCOP = `pkg-config --variable=bin bcop`
-CFLAGS = -g -Wall -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -fno-strict-aliasing `pkg-config --cflags $(PKG_DEP) compiz ` $(CFLAGS_ADD)
+CFLAGS = -g -Wall -Wpointer-arith -fno-strict-aliasing `pkg-config --cflags $(PKG_DEP) compiz ` $(CFLAGS_ADD)
LDFLAGS = `pkg-config --libs $(PKG_DEP) compiz ` $(LDFLAGS_ADD)
DEFINES = -DIMAGEDIR=\"$(IMAGEDIR)\" -DDATADIR=\"$(DATADIR)\"
POFILEDIR = $(shell if [ -n "$(PODIR)" ]; then $(ECHO) $(PODIR); else $(ECHO) ./po;fi )
-COMPIZ_HEADERS = compiz.h compiz-core.h
+COMPIZ_HEADERS = compiz.h core/core.h
COMPIZ_INC = $(shell pkg-config --variable=includedir compiz)/compiz/
is-bcop-target := $(shell if [ -e $(PLUGIN).xml.in ]; then cat $(PLUGIN).xml.in | grep "useBcop=\"true\""; \
@@ -105,7 +105,6 @@ is-bcop-target := $(shell if [ -e $(PLUGIN).xml.in ]; then cat $(PLUGIN).xml.in
trans-target := $(shell if [ -e $(PLUGIN).xml.in -o -e $(PLUGIN).xml ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN).xml;fi )
bcop-target := $(shell if [ -n "$(is-bcop-target)" ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN).xml; fi )
-bcop-target-src := $(shell if [ -n "$(is-bcop-target)" ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN)_options.c; fi )
bcop-target-hdr := $(shell if [ -n "$(is-bcop-target)" ]; then $(ECHO) $(BUILDDIR)/$(PLUGIN)_options.h; fi )
gen-schemas := $(shell if [ \( -e $(PLUGIN).xml.in -o -e $(PLUGIN).xml \) -a -n "`pkg-config --variable=xsltdir compiz-gconf`" ]; then $(ECHO) true; fi )
@@ -119,17 +118,14 @@ endif
# find all the object files
-c-objs := $(patsubst %.c,%.lo,$(shell find -name '*.c' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///'))
-c-objs += $(patsubst %.cpp,%.lo,$(shell find -name '*.cpp' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///'))
+c-objs := $(patsubst %.cpp,%.lo,$(shell find -name '*.cpp' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///'))
c-objs += $(patsubst %.cxx,%.lo,$(shell find -name '*.cxx' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///'))
-c-objs := $(filter-out $(bcop-target-src:.c=.lo),$(c-objs))
h-files := $(shell find -name '*.h' 2> /dev/null | grep -v "$(BUILDDIR)/" | sed -e 's/^.\///')
h-files += $(bcop-target-hdr)
h-files += $(foreach file,$(COMPIZ_HEADERS) $(CHK_HEADERS),$(shell $(ECHO) -n "$(COMPIZ_INC)$(file)"))
all-c-objs := $(addprefix $(BUILDDIR)/,$(c-objs))
-all-c-objs += $(bcop-target-src:.c=.lo)
# additional files
@@ -280,28 +276,6 @@ $(BUILDDIR)/compiz-%.pc: compiz-%.pc.in
# Compiling
#
-$(BUILDDIR)/%.lo: %.c $(h-files)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5mcompiling \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "compiling $< -> $@"; \
- fi
- @$(LIBTOOL) --quiet --mode=compile $(CC) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mcompiling : \033[34m$< -> $@\033[0m"; \
- fi
-
-$(BUILDDIR)/%.lo: $(BUILDDIR)/%.c $(h-files)
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -n -e "\033[0;1;5mcompiling \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
- else \
- $(ECHO) "compiling $< -> $@"; \
- fi
- @$(LIBTOOL) --quiet --mode=compile $(CC) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
- @if [ '$(color)' != 'no' ]; then \
- $(ECHO) -e "\r\033[0mcompiling : \033[34m$< -> $@\033[0m"; \
- fi
-
$(BUILDDIR)/%.lo: %.cpp $(h-files)
@if [ '$(color)' != 'no' ]; then \
$(ECHO) -n -e "\033[0;1;5mcompiling \033[0m: \033[0;32m$< \033[0m-> \033[0;31m$@\033[0m"; \
@@ -319,7 +293,7 @@ $(BUILDDIR)/%.lo: %.cxx $(h-files)
else \
$(ECHO) "compiling $< -> $@"; \
fi
- @$(LIBTOOL) --quiet --mode=compile $(CPP) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
+ @$(LIBTOOL) --mode=compile $(CPP) $(CFLAGS) $(DEFINES) -I$(BUILDDIR) -c -o $@ $<
@if [ '$(color)' != 'no' ]; then \
$(ECHO) -e "\r\033[0mcompiling : \033[34m$< -> $@\033[0m"; \
fi
@@ -336,7 +310,7 @@ $(BUILDDIR)/lib$(PLUGIN).la: $(all-c-objs)
else \
$(ECHO) "linking : $@"; \
fi
- @$(LIBTOOL) --quiet --mode=link $(CC) $(LDFLAGS) -rpath $(DESTDIR) -o $@ $(all-c-objs)
+ @$(LIBTOOL) --quiet --mode=link $(CC) $(LDFLAGS) -rpath $(DESTDIR) -o $@ $(all-c-objs) -R `pkg-config --variable=libdir compiz`/compiz
@if [ '$(color)' != 'no' ]; then \
$(ECHO) -e "\r\033[0mlinking : \033[34m$@\033[0m"; \
fi
diff --git a/plugin.info b/plugin.info
index a97a15b..97e06f4 100644
--- a/plugin.info
+++ b/plugin.info
@@ -1 +1,2 @@
PLUGIN = tile
+PKG_DEP = compiz-composite compiz-opengl
diff --git a/tile.c b/tile.c
deleted file mode 100644
index b54edf8..0000000
--- a/tile.c
+++ /dev/null
@@ -1,1290 +0,0 @@
-/**
- *
- * Compiz tile plugin
- *
- * tile.c
- *
- * Copyright (c) 2006 Atie H. <atie.at.matrix@gmail.com>
- * Copyright (c) 2006 Michal Fojtik <pichalsi(at)gmail.com>
- * Copyright (c) 2007 Danny Baumann <maniac@beryl-project.org>
- *
- * 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
- * of the License, 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.
- *
- * TODO
- * - change vertical and horizontal tiling to similar behavior as Left
- * - fix bugs
- * - make vertical and horizontal maximization be saved when tiling
- *
- **/
-
-#include <string.h>
-#include <math.h>
-#include <compiz-core.h>
-#include "tile_options.h"
-
-static int displayPrivateIndex = 0;
-
-typedef enum {
- NoAnimation = 0,
- Animating,
- AnimationDone
-} WindowAnimationType;
-
-typedef struct _TileDisplay {
- int screenPrivateIndex;
-} TileDisplay;
-
-typedef struct _TileScreen {
- int windowPrivateIndex;
-
- int grabIndex;
- int oneDuration; // duration of animation for one window
- int msResizing; // number of ms elapsed from start of resizing animation
-
- TileTileToggleTypeEnum tileType;
-
- PaintWindowProc paintWindow;
- WindowResizeNotifyProc windowResizeNotify;
- PreparePaintScreenProc preparePaintScreen;
- PaintScreenProc paintScreen;
- DonePaintScreenProc donePaintScreen;
- PaintOutputProc paintOutput;
-} TileScreen;
-
-typedef struct _TileWindow {
- Bool isTiled;
-
- XRectangle savedCoords;
- XRectangle prevCoords;
- XRectangle newCoords;
- unsigned int savedMaxState;
- Bool savedValid;
-
- Bool needConfigure;
- Bool alreadyResized;
-
- WindowAnimationType animationType;
- unsigned int animationNum;
-
- GLushort outlineColor[3];
-} TileWindow;
-
-#define GET_TILE_DISPLAY(d) \
- ((TileDisplay *) (d)->base.privates[displayPrivateIndex].ptr)
-#define TILE_DISPLAY(d) \
- TileDisplay *td = GET_TILE_DISPLAY (d)
-
-#define GET_TILE_SCREEN(s, td) \
- ((TileScreen *) (s)->base.privates[(td)->screenPrivateIndex].ptr)
-#define TILE_SCREEN(s) \
- TileScreen *ts = GET_TILE_SCREEN (s, GET_TILE_DISPLAY (s->display))
-
-#define GET_TILE_WINDOW(w, ts) \
- ((TileWindow *) (w)->base.privates[(ts)->windowPrivateIndex].ptr)
-#define TILE_WINDOW(w) \
- TileWindow *tw = GET_TILE_WINDOW (w, \
- GET_TILE_SCREEN (w->screen, \
- GET_TILE_DISPLAY (w->screen->display)))
-
-static Bool placeWin (CompWindow *w, int x, int y, int width, int height);
-static Bool tileSetNewWindowSize (CompWindow *w);
-
-/* window painting function, draws animation */
-static Bool
-tilePaintWindow(CompWindow *w,
- const WindowPaintAttrib *attrib,
- const CompTransform *transform,
- Region region,
- unsigned int mask)
-{
- CompScreen *s = w->screen;
- Bool status;
- Bool dontDraw = FALSE;
-
- TILE_WINDOW (w);
- TILE_SCREEN (s);
-
- if (tw->animationType != NoAnimation)
- {
- WindowPaintAttrib wAttrib = *attrib;
- CompTransform wTransform = *transform;
- float progress;
-
- progress = (float)ts->msResizing /
- (float)tileGetAnimationDuration (s->display);
-
- switch (tileGetAnimateType (s->display))
- {
- /*
- Drop animation
- */
- case AnimateTypeDropFromTop:
- matrixRotate (&wTransform,
- (progress * 100.0f) - 100.0f,
- 0.0f, 0.0f, 1.0f);
- mask |= PAINT_WINDOW_TRANSFORMED_MASK;
- break;
-
- /*
- Zoom animation
- */
- case AnimateTypeZoom:
- matrixTranslate (&wTransform, 0, 0, progress - 1.0f);
- mask |= PAINT_WINDOW_TRANSFORMED_MASK;
- break;
-
- /*
- Slide animation
- */
- case AnimateTypeSlide:
- if (progress < 0.75f)
- wAttrib.opacity /= 2;
- else
- wAttrib.opacity *= (0.5f + 2 * (progress - 0.75f));
-
- if (ts->msResizing > tw->animationNum * ts->oneDuration)
- {
- /* animation finished */
- tw->animationType = AnimationDone;
- }
- else if (ts->msResizing > (tw->animationNum - 1) *
- ts->oneDuration)
- {
- int thisDur; /* ms spent animating this window */
- thisDur = ts->msResizing % ts->oneDuration;
-
- if (tw->animationNum % 2)
- matrixTranslate (&wTransform,
- s->width - s->width *
- (float)thisDur / ts->oneDuration,
- 0, 0);
- else
- matrixTranslate (&wTransform,
- -s->width + s->width *
- (float)thisDur / ts->oneDuration,
- 0, 0);
-
- mask |= PAINT_WINDOW_TRANSFORMED_MASK;
- }
- else
- dontDraw = TRUE;
- break;
- /*
- Outline animation
- */
- case AnimateTypeFilledOutline:
- dontDraw = TRUE;
- break;
-
- /*
- Fade animation
- */
- case AnimateTypeFade:
- // first half of the animation, fade out
- if (progress < 0.4f)
- wAttrib.opacity -= wAttrib.opacity * progress / 0.4f;
- else
- {
- if (progress > 0.6f && tw->alreadyResized)
- {
- // second half of animation, fade in
- wAttrib.opacity *= (progress - 0.6f) / 0.4f;
- }
- else
- {
- if (tw->needConfigure)
- tileSetNewWindowSize (w);
- dontDraw = TRUE;
- }
- }
- break;
-
- default:
- break;
- }
-
- if (dontDraw)
- mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
-
- UNWRAP (ts, s, paintWindow);
- status = (*s->paintWindow) (w, &wAttrib, &wTransform, region, mask);
- WRAP (ts, s, paintWindow, tilePaintWindow);
- }
- else // paint window as always
- {
- UNWRAP (ts, s, paintWindow);
- status = (*s->paintWindow) (w, attrib, transform, region, mask);
- WRAP (ts, s, paintWindow, tilePaintWindow);
- }
-
- return status;
-}
-
-static void
-tilePreparePaintScreen (CompScreen *s,
- int msSinceLastPaint)
-{
- TILE_SCREEN (s);
-
- // add spent time
- if (ts->grabIndex)
- ts->msResizing += msSinceLastPaint;
-
- UNWRAP (ts, s, preparePaintScreen);
- (*s->preparePaintScreen) (s, msSinceLastPaint);
- WRAP (ts, s, preparePaintScreen, tilePreparePaintScreen);
-}
-
-static void
-tilePaintScreen (CompScreen *s,
- CompOutput *outputs,
- int numOutputs,
- unsigned int mask)
-{
- TILE_SCREEN (s);
-
- if (ts->grabIndex)
- {
- outputs = &s->fullscreenOutput;
- numOutputs = 1;
- }
-
- UNWRAP (ts, s, paintScreen);
- (*s->paintScreen) (s, outputs, numOutputs, mask);
- WRAP (ts, s, paintScreen, tilePaintScreen);
-}
-
-static void
-tileDonePaintScreen (CompScreen *s)
-{
- TILE_SCREEN (s);
-
- if (ts->grabIndex)
- {
- if (ts->msResizing > tileGetAnimationDuration (s->display))
- {
- CompWindow *w;
- for (w = s->windows; w; w = w->next)
- {
- TILE_WINDOW (w);
- tw->animationType = NoAnimation;
- }
-
- ts->msResizing = 0;
-
- removeScreenGrab (s, ts->grabIndex, NULL);
- ts->grabIndex = 0;
- }
-
- damageScreen (s);
- }
-
- UNWRAP (ts, s, donePaintScreen);
- (*s->donePaintScreen) (s);
- WRAP (ts, s, donePaintScreen, tileDonePaintScreen);
-}
-
-static Bool
-tilePaintOutput (CompScreen *s,
- const ScreenPaintAttrib *sa,
- const CompTransform *transform,
- Region region,
- CompOutput *output,
- unsigned int mask)
-{
- Bool status;
-
- TILE_SCREEN (s);
-
- if (ts->grabIndex)
- mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
-
- UNWRAP (ts, s, paintOutput);
- status = (*s->paintOutput) (s, sa, transform, region, output, mask);
- WRAP (ts, s, paintOutput, tilePaintOutput);
-
- /* Check if animation is enabled, there is resizing
- on screen and only outline should be drawn */
-
- if (ts->grabIndex && (output->id == ~0) &&
- (tileGetAnimateType (s->display) == AnimateTypeFilledOutline))
- {
- CompWindow *w;
- CompTransform sTransform = *transform;
- float animationDuration = tileGetAnimationDuration (s->display);
- int x, y, width, height;
-
- transformToScreenSpace (s, output, -DEFAULT_Z_CAMERA, &sTransform);
- glPushMatrix ();
- glLoadMatrixf (sTransform.m);
-
- glLineWidth (4.0f);
-
- for (w = s->windows; w; w = w->next)
- {
- TILE_WINDOW (w);
-
- if (tw->animationType == Animating)
- {
- /* Coordinate = start + speed * elapsedTime
- Coordinate = start + (target - start)/interval * elapsedTime
- Draw outline */
-
- x = tw->prevCoords.x - w->input.left +
- (((float)(w->attrib.x - tw->prevCoords.x)) *
- ts->msResizing / animationDuration);
- y = tw->prevCoords.y - w->input.top +
- (((float)(w->attrib.y - tw->prevCoords.y)) *
- ts->msResizing / animationDuration);
- width = tw->prevCoords.width + w->input.left + w->input.right +
- (((float)(w->attrib.width - tw->prevCoords.width)) *
- ts->msResizing / animationDuration);
- height = tw->prevCoords.height +
- w->input.top + w->input.bottom +
- (((float)(w->attrib.height - tw->prevCoords.height)) *
- ts->msResizing / animationDuration);
-
- glColor3us (tw->outlineColor[0] * 0.66,
- tw->outlineColor[1] * 0.66,
- tw->outlineColor[2] * 0.66);
- glRecti (x, y + height, x + width, y);
-
- glColor3usv (tw->outlineColor);
-
- glBegin (GL_LINE_LOOP);
- glVertex3f (x, y, 0.0f);
- glVertex3f (x + width, y, 0.0f);
- glVertex3f (x + width, y + height, 0.0f);
- glVertex3f (x, y + height, 0.0f);
- glEnd ();
-
- glColor4usv (defaultColor);
- }
- }
-
- glPopMatrix ();
- glColor4usv (defaultColor);
- glLineWidth (1.0f);
- }
-
- return status;
-}
-
-/* Resize notify used when windows are tiled horizontally or vertically */
-static void
-tileResizeNotify (CompWindow *w,
- int dx,
- int dy,
- int dwidth,
- int dheight)
-{
- TILE_SCREEN (w->screen);
- TILE_WINDOW (w);
-
- UNWRAP (ts, w->screen, windowResizeNotify);
- (*w->screen->windowResizeNotify) (w, dx, dy, dwidth, dheight);
- WRAP (ts, w->screen, windowResizeNotify, tileResizeNotify);
-
- if (!tw->alreadyResized)
- {
- tw->alreadyResized = TRUE;
- return;
- }
-
- /* Dont do anything if joining is disabled or windows are being resized */
- if (tileGetTileJoin (w->screen->display) && !ts->grabIndex)
- {
- CompWindow *prev = NULL, *next = NULL, *cw;
- Bool windowSeen = FALSE;
-
- /* determine previous and next tiled window */
- for (cw = w->screen->reverseWindows; cw; cw = cw->prev)
- {
- if (windowSeen)
- {
- next = cw;
- break;
- }
- else
- {
- if (cw != w)
- prev = cw;
- else
- windowSeen = TRUE;
- }
- }
-
- switch (ts->tileType)
- {
- case TileToggleTypeTile:
- if (prev)
- placeWin (prev,
- prev->attrib.x, prev->attrib.y,
- w->attrib.x - prev->attrib.x -
- w->input.left - prev->input.right,
- prev->height);
-
- if (next)
- {
- int currentX;
- currentX = w->attrib.x + w->width +
- w->input.right + next->input.left;
- placeWin (next, currentX, next->attrib.y,
- next->width + next->attrib.x - currentX,
- next->height);
- }
- break;
-
- case TileToggleTypeTileHorizontally:
- if (prev)
- placeWin (prev,
- prev->attrib.x, prev->attrib.y,
- prev->width,
- w->attrib.y - prev->attrib.y -
- w->input.top - prev->input.bottom);
-
- if (next)
- {
- int currentY;
- currentY = w->attrib.y + w->height +
- w->input.bottom + next->input.top;
- placeWin (next, next->attrib.x,
- currentY, next->width,
- next->height + next->attrib.y - currentY);
- }
- break;
- case TileToggleTypeLeft:
- if (!next && prev && dwidth) /* last window - on the left */
- {
- XRectangle workArea;
- int currentX;
-
- workArea = w->screen->workArea;
-
- for (cw = w->screen->windows; cw; cw = cw->next)
- {
- TILE_WINDOW(cw);
-
- if (!tw->isTiled || (cw->id == w->id))
- continue;
-
- currentX = workArea.x + w->serverX +
- w->serverWidth + w->input.right + cw->input.left;
-
- placeWin (cw, currentX, cw->attrib.y,
- workArea.width - currentX - w->input.right,
- cw->attrib.height);
- }
- }
- else if (next) /* windows on the right */
- {
- XRectangle workArea;
- Bool first = TRUE;
-
- workArea = w->screen->workArea;
-
- for (cw = w->screen->windows; cw; cw = cw->next)
- {
- TILE_WINDOW (cw);
-
- if (!tw->isTiled || (cw->id == w->id))
- continue;
-
- if (first)
- {
- placeWin (cw,
- workArea.x + cw->input.left, cw->attrib.y,
- w->serverX - w->input.left -
- cw->input.left - cw->input.right - workArea.x,
- cw->attrib.height);
-
- first = FALSE;
- }
- else
- {
- int x = cw->attrib.x;
- int y = cw->attrib.y;
- int width = cw->attrib.width;
- int height = cw->attrib.height;
-
- if (prev && (cw->id == prev->id))
- height = w->serverY - cw->attrib.y -
- w->input.top - cw->input.bottom;
- else if (next && (cw->id == next->id))
- y = w->serverY + w->serverHeight +
- w->input.bottom + cw->input.top;
-
- x = w->serverX;
- width = workArea.width + workArea.x -
- w->serverX - w->input.right;
-
- placeWin (cw, x, y, width, height);
- }
- }
- }
- break;
-
- default:
- break;
- }
- }
-}
-
-static Bool
-tileInitScreen (CompPlugin *p,
- CompScreen *s)
-{
- TileScreen *ts;
-
- TILE_DISPLAY (s->display);
-
- ts = (TileScreen *) calloc (1, sizeof (TileScreen));
-
- ts->windowPrivateIndex = allocateWindowPrivateIndex (s);
- if (ts->windowPrivateIndex < 0)
- {
- free (ts);
- return FALSE;
- }
- srand (time (0));
-
- s->base.privates[td->screenPrivateIndex].ptr = ts;
-
- ts->grabIndex = 0;
- ts->msResizing = 0;
- ts->oneDuration = 0;
-
- /* Wrap plugin functions */
- WRAP (ts, s, paintOutput, tilePaintOutput);
- WRAP (ts, s, preparePaintScreen, tilePreparePaintScreen);
- WRAP (ts, s, paintScreen, tilePaintScreen);
- WRAP (ts, s, donePaintScreen, tileDonePaintScreen);
- WRAP (ts, s, windowResizeNotify, tileResizeNotify);
- WRAP (ts, s, paintWindow, tilePaintWindow);
-
- return TRUE;
-}
-
-static void
-tileFiniScreen (CompPlugin *p,
- CompScreen *s)
-{
- TILE_SCREEN (s);
-
- freeWindowPrivateIndex (s, ts->windowPrivateIndex);
-
- /* Restore the original function */
- UNWRAP (ts, s, paintOutput);
- UNWRAP (ts, s, preparePaintScreen);
- UNWRAP (ts, s, paintScreen);
- UNWRAP (ts, s, donePaintScreen);
- UNWRAP (ts, s, windowResizeNotify);
- UNWRAP (ts, s, paintWindow);
-
- free (ts);
-}
-
-/* this is resizeConstrainMinMax from resize.c,
- thanks to David Reveman/Nigel Cunningham */
-static void
-constrainMinMax (CompWindow *w,
- int width,
- int height,
- int *newWidth,
- int *newHeight)
-{
- const XSizeHints *hints = &w->sizeHints;
- int min_width = 0;
- int min_height = 0;
- int max_width = MAXSHORT;
- int max_height = MAXSHORT;
-
- if ((hints->flags & PBaseSize) && (hints->flags & PMinSize))
- {
- min_width = hints->min_width;
- min_height = hints->min_height;
- }
- else if (hints->flags & PBaseSize)
- {
- min_width = hints->base_width;
- min_height = hints->base_height;
- }
- else if (hints->flags & PMinSize)
- {
- min_width = hints->min_width;
- min_height = hints->min_height;
- }
-
- if (hints->flags & PMaxSize)
- {
- max_width = hints->max_width;
- max_height = hints->max_height;
- }
-#define CLAMP(v, min, max) ((v) <= (min) ? (min) : (v) >= (max) ? (max) : (v))
-
- /* clamp width and height to min and max values */
- width = CLAMP (width, min_width, max_width);
- height = CLAMP (height, min_height, max_height);
-
-#undef CLAMP
-
- *newWidth = width;
- *newHeight = height;
-}
-
-/* Moves window to [x,y] and resizes to width x height
- if no animation or starts animation */
-static Bool
-placeWin (CompWindow *w,
- int x,
- int y,
- int width,
- int height)
-{
- /* window existence check */
- if (!w)
- return FALSE;
-
- /* this checks if the window isnt smaller
- than minimum size it has defined */
- constrainMinMax (w, width, height, &width, &height);
-
- /* check if the window isnt already where its going to be */
- if (x == w->attrib.x && y == w->attrib.y &&
- width == w->attrib.width && height == w->attrib.height)
- return TRUE;
-
- TILE_WINDOW(w);
-
- /* set previous coordinates for animation */
- tw->prevCoords.x = w->attrib.x;
- tw->prevCoords.y = w->attrib.y;
- tw->prevCoords.width = w->attrib.width;
- tw->prevCoords.height = w->attrib.height;
-
- /* set future coordinates for animation */
- tw->newCoords.x = x;
- tw->newCoords.y = y;
- tw->newCoords.width = width;
- tw->newCoords.height = height;
-
- tw->alreadyResized = FALSE; /* window is not resized now */
- tw->needConfigure = TRUE;
-
- switch (tileGetAnimateType (w->screen->display))
- {
- case AnimateTypeNone:
- tileSetNewWindowSize (w);
- break;
- case AnimateTypeFilledOutline:
- case AnimateTypeSlide:
- case AnimateTypeZoom:
- case AnimateTypeDropFromTop:
- tileSetNewWindowSize (w);
- /* fall-through */
- case AnimateTypeFade:
- tw->animationType = Animating;
- break;
- default:
- break;
- }
-
- return TRUE;
-}
-
-static Bool
-tileSetNewWindowSize (CompWindow *w)
-{
- XWindowChanges xwc;
- unsigned int mask = CWX | CWY | CWWidth | CWHeight;
-
- TILE_WINDOW (w);
- TILE_SCREEN (w->screen);
-
- xwc.x = tw->newCoords.x;
- xwc.y = tw->newCoords.y;
- xwc.width = tw->newCoords.width;
- xwc.height = tw->newCoords.height;
-
- if (ts->tileType == -1)
- {
- if (tw->savedValid)
- maximizeWindow (w, tw->savedMaxState);
- }
- else
- maximizeWindow (w, 0);
-
- if (xwc.width == w->serverWidth)
- mask &= ~CWWidth;
-
- if (xwc.height == w->serverHeight)
- mask &= ~CWHeight;
-
- if (w->mapNum && (mask & (CWWidth | CWHeight)))
- sendSyncRequest (w);
-
- configureXWindow (w, mask, &xwc);
- tw->needConfigure = FALSE;
-
- return TRUE;
-}
-
-/* Heavily inspired by windowIs3D and isSDWindow,
- returns TRUE if the window is usable for tiling */
-static Bool
-isTileWindow (CompWindow *w)
-{
- if (matchEval (tileGetExcludeMatch (w->screen->display), w))
- return FALSE;
-
- if (w->attrib.override_redirect)
- return FALSE;
-
- if (!((*w->screen->focusWindow) (w)))
- return FALSE;
-
- if (w->wmType & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
- return FALSE;
-
- if (w->state & CompWindowStateSkipPagerMask)
- return FALSE;
-
- if (w->minimized || !w->placed)
- return FALSE;
-
- return TRUE;
-}
-
-/* save window coordinates to use for restore */
-static void
-saveCoords (CompWindow *w)
-{
- TILE_WINDOW (w);
-
- if (tw->savedValid)
- return;
-
- tw->savedCoords.x = w->serverX;
- tw->savedCoords.y = w->serverY;
- tw->savedCoords.width = w->serverWidth;
- tw->savedCoords.height = w->serverHeight;
-
- tw->savedMaxState = w->state & MAXIMIZE_STATE;
-
- tw->savedValid = TRUE;
-}
-
-/* Applies tiling/restoring */
-static Bool
-applyTiling (CompScreen *s)
-{
- CompWindow *w;
- int count = 0;
-
- TILE_SCREEN (s);
-
- if (ts->grabIndex)
- return FALSE;
-
- for (w = s->windows; w; w = w->next)
- {
- if (isTileWindow (w))
- count++;
- }
-
- ts->oneDuration = tileGetAnimationDuration (s->display) / MAX (count, 1);
-
- if (count > 1)
- {
- int countX = 0, countY = 0;
- int currentX = 0, currentY = 0;
- int winWidth = 0, winHeight = 0;
- int x = 0, y = 0;
- int height = 0, occupancy = 0, delta = 0;
- Bool first = TRUE;
- int i = 0;
- XRectangle workArea;
- CompWindowExtents border;
-
- memset (&border, 0, sizeof (CompWindowExtents));
- /* first get the largest border of the windows on this
- screen - some of the windows in our list might be
- maximized now and not be maximized later, so
- their border information may be inaccurate */
- for (w = s->windows; w; w = w->next)
- {
- if (w->input.left > border.left)
- border.left = w->input.left;
- if (w->input.right > border.right)
- border.right = w->input.right;
- if (w->input.top > border.top)
- border.top = w->input.top;
- if (w->input.bottom > border.bottom)
- border.bottom = w->input.bottom;
- }
-
- workArea = s->workArea;
-
- switch (ts->tileType)
- {
- case TileToggleTypeTile:
- countX = ceil (sqrt (count));
- countY = ceil ((float)count / countX);
- currentX = workArea.x;
- currentY = workArea.y;
- winWidth = workArea.width / countX;
- winHeight = workArea.height / countY;
- break;
- case TileToggleTypeLeft:
- height = workArea.height / (count - 1);
- occupancy = tileGetTileLeftOccupancy (s->display);
- break;
- case TileToggleTypeTileVertically:
- winWidth = workArea.width / count;
- winHeight = workArea.height;
- y = workArea.y;
- break;
- case TileToggleTypeTileHorizontally:
- winWidth = workArea.width;
- winHeight = workArea.height / count;
- x = workArea.x;
- break;
- case TileToggleTypeCascade:
- delta = tileGetTileDelta (s->display);
- currentX = workArea.x;
- currentY = workArea.y;
- winHeight = workArea.height - delta * (count - 1);
- winWidth = workArea.width - delta * (count - 1);
- break;
- default:
- break;
- }
-
- for (w = s->windows; w; w = w->next)
- {
- if (!isTileWindow (w))
- continue;
-
- TILE_WINDOW (w);
-
- if (!tw->savedValid)
- saveCoords (w);
-
- switch (ts->tileType)
- {
- case TileToggleTypeTile:
- placeWin(w,
- currentX + border.left, currentY + border.top,
- winWidth - (border.left + border.right),
- winHeight - (border.top + border.bottom));
- tw->isTiled = TRUE;
- break;
- case TileToggleTypeLeft:
- if (first)
- {
- x = workArea.x;
- y = workArea.y;
- winWidth = workArea.width * occupancy / 100;
- winHeight = workArea.height;
- first = FALSE;
- }
- else
- {
- x = workArea.x + (workArea.width * occupancy / 100);
- y = workArea.y + (i * height);
- winWidth = (workArea.width * (100 - occupancy) / 100);
- winHeight = height;
- }
-
- placeWin(w,
- x + border.left, y + border.top,
- winWidth - (border.left + border.right),
- winHeight - (border.top + border.bottom));
- tw->isTiled = TRUE;
- break;
- case TileToggleTypeTileVertically:
- x = workArea.x + (winWidth * i);
- placeWin(w,
- x + border.left, y + border.top,
- winWidth - (border.left + border.right),
- winHeight - (border.top + border.bottom));
- tw->isTiled = TRUE;
- break;
- case TileToggleTypeTileHorizontally:
- y = workArea.y + (winHeight * i);
- placeWin (w, x + border.left, y + border.top,
- winWidth - (border.left + border.right),
- winHeight - (border.top + border.bottom));
- tw->isTiled = TRUE;
- break;
- case TileToggleTypeCascade:
- placeWin (w,
- currentX + border.left, currentY + border.top,
- winWidth - (border.left + border.right),
- winHeight - (border.top + border.bottom));
- tw->isTiled = TRUE;
- break;
- case -1:
- if (tw->isTiled)
- {
- placeWin (w,
- tw->savedCoords.x, tw->savedCoords.y,
- tw->savedCoords.width, tw->savedCoords.height);
- tw->savedValid = FALSE;
- tw->isTiled = FALSE;
- }
- break;
- default:
- break;
- }
-
- i++;
- tw->animationNum = i;
-
- switch (ts->tileType)
- {
- case TileToggleTypeTile:
- if (!(i % countX))
- {
- currentX = workArea.x;
- currentY += winHeight;
- }
- else
- currentX += winWidth;
- break;
- case TileToggleTypeCascade:
- currentX += delta;
- currentY += delta;
- default:
- break;
- }
- }
-
- if (!ts->grabIndex)
- ts->grabIndex = pushScreenGrab (s, s->invisibleCursor, "tile");
-
- ts->msResizing = 0;
- }
-
- return TRUE;
-}
-
-static Bool
-tileTile (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompScreen *s;
- Window xid;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
- s = findScreenAtDisplay (d, xid);
-
- if (s)
- {
- TILE_SCREEN (s);
-
- ts->tileType = TileToggleTypeTile;
- applyTiling (s);
- }
-
- return FALSE;
-}
-
-static Bool
-tileVertically (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompScreen *s;
- Window xid;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
- s = findScreenAtDisplay (d, xid);
-
- if (s)
- {
- TILE_SCREEN (s);
-
- ts->tileType = TileToggleTypeTileVertically;
- applyTiling (s);
- }
-
- return FALSE;
-}
-
-static Bool
-tileHorizontally (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompScreen *s;
- Window xid;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
- s = findScreenAtDisplay (d, xid);
-
- if (s)
- {
- TILE_SCREEN (s);
-
- ts->tileType = TileToggleTypeTileHorizontally;
- applyTiling (s);
- }
-
- return FALSE;
-}
-
-static Bool
-tileCascade (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompScreen *s;
- Window xid;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
- s = findScreenAtDisplay (d, xid);
-
- if (s)
- {
- TILE_SCREEN (s);
-
- ts->tileType = TileToggleTypeCascade;
- applyTiling (s);
- }
-
- return FALSE;
-}
-
-static Bool
-tileRestore (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompScreen *s;
- Window xid;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
- s = findScreenAtDisplay (d, xid);
-
- if (s)
- {
- TILE_SCREEN (s);
-
- ts->tileType = -1;
- applyTiling (s);
- }
-
- return FALSE;
-}
-
-static Bool
-tileToggle (CompDisplay *d,
- CompAction *action,
- CompActionState state,
- CompOption *option,
- int nOption)
-{
- CompScreen *s;
- Window xid;
-
- xid = getIntOptionNamed (option, nOption, "root", 0);
- s = findScreenAtDisplay (d, xid);
-
- if (s)
- {
- CompWindow *w;
-
- TILE_SCREEN (s);
-
- for (w = s->windows; w; w = w->next)
- {
- TILE_WINDOW (w);
- if (tw->isTiled)
- break;
- }
-
- if (w)
- {
- ts->tileType = -1;
- applyTiling (s);
- }
- else
- {
- ts->tileType = tileGetTileToggleType (d);
- applyTiling (s);
- }
- }
-
- return FALSE;
-}
-
-static Bool
-tileInitDisplay (CompPlugin *p,
- CompDisplay *d)
-{
- TileDisplay *td;
-
- if (!checkPluginABI ("core", CORE_ABIVERSION))
- return FALSE;
-
- td = malloc (sizeof (TileDisplay));
- if (!td)
- return FALSE;
-
- /* Allocate a private index */
- td->screenPrivateIndex = allocateScreenPrivateIndex (d);
-
- /* Check if its valid */
- if (td->screenPrivateIndex < 0)
- {
- free (td);
- return FALSE;
- }
-
- tileSetTileVerticallyKeyInitiate (d, tileVertically);
- tileSetTileHorizontallyKeyInitiate (d, tileHorizontally);
- tileSetTileTileKeyInitiate (d, tileTile);
- tileSetTileCascadeKeyInitiate (d, tileCascade);
- tileSetTileRestoreKeyInitiate (d, tileRestore);
- tileSetTileToggleKeyInitiate (d, tileToggle);
-
- /* Record the display */
- d->base.privates[displayPrivateIndex].ptr = td;
-
- return TRUE;
-}
-
-static void
-tileFiniDisplay (CompPlugin *p,
- CompDisplay *d)
-{
- TILE_DISPLAY (d);
-
- /* Free the private index */
- freeScreenPrivateIndex (d, td->screenPrivateIndex);
-
- free (td);
-}
-
-static Bool
-tileInitWindow (CompPlugin *p,
- CompWindow *w)
-{
- TileWindow *tw;
-
- TILE_SCREEN (w->screen);
-
- tw = malloc (sizeof (TileWindow));
- if (!tw)
- return FALSE;
-
- memset (&tw->newCoords, 0, sizeof (XRectangle));
- memset (&tw->prevCoords, 0, sizeof (XRectangle));
- memset (&tw->savedCoords, 0, sizeof (XRectangle));
-
- tw->savedValid = FALSE;
- tw->animationType = NoAnimation;
- tw->savedMaxState = 0;
- tw->isTiled = FALSE;
- tw->needConfigure = FALSE;
-
- /* random color, from group.c thanks to the author for doing it */
- tw->outlineColor[0] = rand() % 0xFFFF;
- tw->outlineColor[1] = rand() % 0xFFFF;
- tw->outlineColor[2] = rand() % 0xFFFF;
-
- w->base.privates[ts->windowPrivateIndex].ptr = tw;
-
- return TRUE;
-}
-
-static void
-tileFiniWindow (CompPlugin *p,
- CompWindow *w)
-{
- TILE_WINDOW (w);
-
- free (tw);
-}
-
-static CompBool
-tileInitObject (CompPlugin *p,
- CompObject *o)
-{
- static InitPluginObjectProc dispTab[] = {
- (InitPluginObjectProc) 0, /* InitCore */
- (InitPluginObjectProc) tileInitDisplay,
- (InitPluginObjectProc) tileInitScreen,
- (InitPluginObjectProc) tileInitWindow
- };
-
- RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
-}
-
-static void
-tileFiniObject (CompPlugin *p,
- CompObject *o)
-{
- static FiniPluginObjectProc dispTab[] = {
- (FiniPluginObjectProc) 0, /* FiniCore */
- (FiniPluginObjectProc) tileFiniDisplay,
- (FiniPluginObjectProc) tileFiniScreen,
- (FiniPluginObjectProc) tileFiniWindow
- };
-
- DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
-}
-
-static Bool
-tileInit (CompPlugin *p)
-{
- displayPrivateIndex = allocateDisplayPrivateIndex ();
-
- if (displayPrivateIndex < 0)
- return FALSE;
-
- return TRUE;
-}
-
-static void
-tileFini (CompPlugin * p)
-{
- freeDisplayPrivateIndex (displayPrivateIndex);
-}
-
-CompPluginVTable tileVTable = {
- "tile",
- 0,
- tileInit,
- tileFini,
- tileInitObject,
- tileFiniObject,
- 0,
- 0
-};
-
-CompPluginVTable*
-getCompPluginInfo (void)
-{
- return &tileVTable;
-}
diff --git a/tile.cpp b/tile.cpp
new file mode 100644
index 0000000..a5835e8
--- /dev/null
+++ b/tile.cpp
@@ -0,0 +1,1075 @@
+/**
+ *
+ * Compiz tile plugin
+ *
+ * tile.c
+ *
+ * Copyright (c) 2006 Atie H. <atie.at.matrix@gmail.com>
+ * Copyright (c) 2006 Michal Fojtik <pichalsi(at)gmail.com>
+ * Copyright (c) 2007 Danny Baumann <maniac@beryl-project.org>
+ *
+ * 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
+ * of the License, 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.
+ *
+ * TODO
+ * - change vertical and horizontal tiling to similar behavior as Left
+ * - fix bugs
+ * - make vertical and horizontal maximization be saved when tiling
+ *
+ **/
+
+/* TODO: Right now we are tiling immediately with no animation, fix that */
+/* FIX: Should check if window can be resized to amount we want, otherwise
+ don't include that window */
+
+#include "tile.h"
+
+COMPIZ_PLUGIN_20081216 (tile, TilePluginVTable);
+
+/* window painting function, draws animation */
+bool
+TileWindow::glPaint (const GLWindowPaintAttrib &attrib,
+ const GLMatrix &transform,
+ CompRegion &region,
+ unsigned int mask)
+{
+ bool status;
+#if 0
+ bool dontDraw = false;
+ if (tw->animationType != NoAnimation)
+ {
+ WindowPaintAttrib wAttrib = *attrib;
+ CompTransform wTransform = *transform;
+ float progress;
+
+ progress = (float)ts->msResizing /
+ (float)tileGetAnimationDuration (s->display);
+
+ switch (tileGetAnimateType (s->display))
+ {
+ /*
+ Drop animation
+ */
+ case AnimateTypeDropFromTop:
+ matrixRotate (&wTransform,
+ (progress * 100.0f) - 100.0f,
+ 0.0f, 0.0f, 1.0f);
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+ break;
+
+ /*
+ Zoom animation
+ */
+ case AnimateTypeZoom:
+ matrixTranslate (&wTransform, 0, 0, progress - 1.0f);
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+ break;
+
+ /*
+ Slide animation
+ */
+ case AnimateTypeSlide:
+ if (progress < 0.75f)
+ wAttrib.opacity /= 2;
+ else
+ wAttrib.opacity *= (0.5f + 2 * (progress - 0.75f));
+
+ if (ts->msResizing > tw->animationNum * ts->oneDuration)
+ {
+ /* animation finished */
+ tw->animationType = AnimationDone;
+ }
+ else if (ts->msResizing > (tw->animationNum - 1) *
+ ts->oneDuration)
+ {
+ int thisDur; /* ms spent animating this window */
+ thisDur = ts->msResizing % ts->oneDuration;
+
+ if (tw->animationNum % 2)
+ matrixTranslate (&wTransform,
+ s->width - s->width *
+ (float)thisDur / ts->oneDuration,
+ 0, 0);
+ else
+ matrixTranslate (&wTransform,
+ -s->width + s->width *
+ (float)thisDur / ts->oneDuration,
+ 0, 0);
+
+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
+ }
+ else
+ dontDraw = true;
+ break;
+ /*
+ Outline animation
+ */
+ case AnimateTypeFilledOutline:
+ dontDraw = true;
+ break;
+
+ /*
+ Fade animation
+ */
+ case AnimateTypeFade:
+ // first half of the animation, fade out
+ if (progress < 0.4f)
+ wAttrib.opacity -= wAttrib.opacity * progress / 0.4f;
+ else
+ {
+ if (progress > 0.6f && tw->alreadyResized)
+ {
+ // second half of animation, fade in
+ wAttrib.opacity *= (progress - 0.6f) / 0.4f;
+ }
+ else
+ {
+ if (tw->needConfigure)
+ tileSetNewWindowSize (w);
+ dontDraw = true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (dontDraw)
+ mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
+
+ UNWRAP (ts, s, paintWindow);
+ status = (*s->paintWindow) (w, &wAttrib, &wTransform, region, mask);
+ WRAP (ts, s, paintWindow, tilePaintWindow);
+ }
+ else // paint window as always
+#endif
+
+ status = gWindow->glPaint (attrib, transform, region, mask);
+
+ return status;
+}
+
+void
+TileScreen::preparePaint (int msSinceLastPaint)
+{
+#if 0
+ // add spent time
+ if (state == In || state == Out)
+ ts->msResizing += msSinceLastPaint;
+#endif
+ cScreen->preparePaint (msSinceLastPaint);
+}
+#if 0
+void
+TileScreen::glPaintScreen (CompOutput *outputs,
+ int numOutputs,
+ unsigned int mask)
+{
+ if (state == In || state == Out)
+ {
+ /* We want to ensure that we are painting the fullscreen output */
+ outputs = &screen->fullscreenOutput ();
+ numOutputs = 1;
+ }
+
+ gScreen->glPaintScreen (outputs, numOutputs, mask);
+}
+#endif
+void
+TileScreen::donePaint ()
+{
+#if 0
+ if (state == In || state == Out)
+ {
+ if (msResizing > tileGetAnimationDuration (s->display))
+ {
+ foreach (CompWindow *w, screen->windows ())
+ {
+ TILE_WINDOW (w);
+ //tw->animationType = NoAnimation;
+ }
+
+ //ts->msResizing = 0;
+
+ if (state == In)
+ state = Tiled;
+ else if (state == Out)
+ state = Normal;
+ }
+
+ cScreen->damageScreen ();
+ }
+#endif
+ cScreen->donePaint ();
+}
+
+bool
+TileScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ CompRegion &region,
+ CompOutput *output,
+ unsigned int mask)
+{
+ bool status;
+
+ if (state == In || state == Out)
+ mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
+
+ status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
+
+ /* Check if animation is enabled, there is resizing
+ on screen and only outline should be drawn */
+
+#if 0
+ if ((state == In || state == Out) && (output->id () == ~0) &&
+ (optionGetAnimateType () == TileOptions::AnimateTypeFilledOutline))
+ {
+ GLMatrix sTransform = transform;
+ float animationDuration = optionGetAnimationDuration ();
+ int x, y, width, height;
+
+ sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
+ glPushMatrix ();
+ glLoadMatrixf (sTransform.getMatrix ());
+
+ glLineWidth (4.0f);
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ TILE_WINDOW (w);
+ if (tw->animationType == Animating)
+ {
+ /* Coordinate = start + speed * elapsedTime
+ Coordinate = start + (target - start)/interval * elapsedTime
+ Draw outline */
+
+ x = tw->tiler->previous.x () - w->input ().left +
+ (((float)(w->x () - tw->previous.x ())) *
+ ts->msResizing / animationDuration);
+ y = tw->previous.y () - w->input ().top +
+ (((float)(w->y () - tw->previous.y ())) *
+ ts->msResizing / animationDuration);
+ width = tw->previous.width () + w->input ().left + w->input ().right +
+ (((float)(w->width () - tw->previous.width ())) *
+ ts->msResizing / animationDuration);
+ height = tw->previous.height () +
+ w->input ().top + w->input ().bottom +
+ (((float)(w->height () - tw->previous.height ())) *
+ ts->msResizing / animationDuration);
+
+ glColor3us (tw->outlineColor[0] * 0.66,
+ tw->outlineColor[1] * 0.66,
+ tw->outlineColor[2] * 0.66);
+ glRecti (x, y + height, x + width, y);
+
+ glColor3usv (tw->outlineColor);
+
+ glBegin (GL_LINE_LOOP);
+ glVertex3f (x, y, 0.0f);
+ glVertex3f (x + width, y, 0.0f);
+ glVertex3f (x + width, y + height, 0.0f);
+ glVertex3f (x, y + height, 0.0f);
+ glEnd ();
+
+ glColor4usv (defaultColor);
+ }
+ }
+ glPopMatrix ();
+ glColor4usv (defaultColor);
+ glLineWidth (1.0f);
+ }
+#endif
+
+ return status;
+}
+
+/* Resize notify used when windows are tiled horizontally or vertically */
+void
+TileWindow::resizeNotify (int dx,
+ int dy,
+ int dwidth,
+ int dheight)
+{
+ window->resizeNotify (dx, dy, dwidth, dheight);
+
+ if (!alreadyResized)
+ {
+ alreadyResized = true;
+ return;
+ }
+#if 0
+//WE WILL MOVE THIS TO A DIFFERENT PLUGIN
+ /* Dont do anything if joining is disabled or windows are being resized */
+ if (tileGetTileJoin (w->screen->display) && !ts->grabIndex)
+ {
+ CompWindow *prev = NULL, *next = NULL, *cw;
+ bool windowSeen = false;
+
+ /* determine previous and next tiled window */
+ for (cw = w->screen->reverseWindows; cw; cw = cw->prev)
+ {
+ if (windowSeen)
+ {
+ next = cw;
+ break;
+ }
+ else
+ {
+ if (cw != w)
+ prev = cw;
+ else
+ windowSeen = true;
+ }
+ }
+
+ switch (ts->tileType)
+ {
+ case TileToggleTypeTile:
+ if (prev)
+ placeWin (prev,
+ prev->attrib.x, prev->attrib.y,
+ w->attrib.x - prev->attrib.x -
+ w->input.left - prev->input.right,
+ prev->height);
+
+ if (next)
+ {
+ int currentX;
+ currentX = w->attrib.x + w->width +
+ w->input.right + next->input.left;
+ placeWin (next, currentX, next->attrib.y,
+ next->width + next->attrib.x - currentX,
+ next->height);
+ }
+ break;
+
+ case TileToggleTypeTileHorizontally:
+ if (prev)
+ placeWin (prev,
+ prev->attrib.x, prev->attrib.y,
+ prev->width,
+ w->attrib.y - prev->attrib.y -
+ w->input.top - prev->input.bottom);
+
+ if (next)
+ {
+ int currentY;
+ currentY = w->attrib.y + w->height +
+ w->input.bottom + next->input.top;
+ placeWin (next, next->attrib.x,
+ currentY, next->width,
+ next->height + next->attrib.y - currentY);
+ }
+ break;
+ case TileToggleTypeLeft:
+ if (!next && prev && dwidth) /* last window - on the left */
+ {
+ XRectangle workArea;
+ int currentX;
+
+ workArea = w->screen->workArea;
+
+ for (cw = w->screen->windows; cw; cw = cw->next)
+ {
+ TILE_WINDOW(cw);
+
+ if (!tw->isTiled || (cw->id == w->id))
+ continue;
+
+ currentX = workArea.x + w->serverX +
+ w->serverWidth + w->input.right + cw->input.left;
+
+ placeWin (cw, currentX, cw->attrib.y,
+ workArea.width - currentX - w->input.right,
+ cw->attrib.height);
+ }
+ }
+ else if (next) /* windows on the right */
+ {
+ XRectangle workArea;
+ bool first = true;
+
+ workArea = w->screen->workArea;
+
+ for (cw = w->screen->windows; cw; cw = cw->next)
+ {
+ TILE_WINDOW (cw);
+
+ if (!tw->isTiled || (cw->id == w->id))
+ continue;
+
+ if (first)
+ {
+ placeWin (cw,
+ workArea.x + cw->input.left, cw->attrib.y,
+ w->serverX - w->input.left -
+ cw->input.left - cw->input.right - workArea.x,
+ cw->attrib.height);
+
+ first = false;
+ }
+ else
+ {
+ int x = cw->attrib.x;
+ int y = cw->attrib.y;
+ int width = cw->attrib.width;
+ int height = cw->attrib.height;
+
+ if (prev && (cw->id == prev->id))
+ height = w->serverY - cw->attrib.y -
+ w->input.top - cw->input.bottom;
+ else if (next && (cw->id == next->id))
+ y = w->serverY + w->serverHeight +
+ w->input.bottom + cw->input.top;
+
+ x = w->serverX;
+ width = workArea.width + workArea.x -
+ w->serverX - w->input.right;
+
+ placeWin (cw, x, y, width, height);
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+#endif
+}
+
+/* this is resizeConstrainMinMax from resize.c,
+ thanks to David Reveman/Nigel Cunningham */
+void
+TileWindow::constrainMinMax (int width,
+ int height,
+ int &newWidth,
+ int &newHeight)
+{
+ const XSizeHints *hints = &window->sizeHints ();
+ int min_width = 0;
+ int min_height = 0;
+ int max_width = MAXSHORT;
+ int max_height = MAXSHORT;
+
+ if ((hints->flags & PBaseSize) && (hints->flags & PMinSize))
+ {
+ min_width = hints->min_width;
+ min_height = hints->min_height;
+ }
+ else if (hints->flags & PBaseSize)
+ {
+ min_width = hints->base_width;
+ min_height = hints->base_height;
+ }
+ else if (hints->flags & PMinSize)
+ {
+ min_width = hints->min_width;
+ min_height = hints->min_height;
+ }
+
+ if (hints->flags & PMaxSize)
+ {
+ max_width = hints->max_width;
+ max_height = hints->max_height;
+ }
+#define CLAMP(v, min, max) ((v) <= (min) ? (min) : (v) >= (max) ? (max) : (v))
+
+ /* clamp width and height to min and max values */
+ width = CLAMP (width, min_width, max_width);
+ height = CLAMP (height, min_height, max_height);
+
+#undef CLAMP
+
+ newWidth = width;
+ newHeight = height;
+}
+
+/* Moves window to [x,y] and resizes to width x height
+ if no animation or starts animation */
+
+bool
+TileWindow::placeWin (int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ /* Workaround for g++ warnings */
+ int i_width;
+ int i_height;
+ /* this checks if the window isnt smaller
+ than minimum size it has defined */
+ constrainMinMax (i_width, i_height, i_width, i_height);
+
+ width = i_width;
+ height = i_height;
+
+ /* does the window need to be moved? */
+ if (x == window->x () && y == window->y () &&
+ width == window->width () && height == window->height ())
+ return true;
+
+ if (!tiler)
+ return false;
+
+ /* set previous coordinates for animation */
+ tiler->previous.setGeometry (window->x (), window->y (),
+ window->width (), window->height ());
+
+ /* set future coordinates for animation */
+ tiler->current.setGeometry (x, y, width, height);
+
+ alreadyResized = false; /* window is not resized now */
+ needConfigure = true;
+#if 0
+ switch (tileGetAnimateType (w->screen->display))
+ {
+ case AnimateTypeNone:
+ tileSetNewWindowSize (w);
+ break;
+ case AnimateTypeFilledOutline:
+ case AnimateTypeSlide:
+ case AnimateTypeZoom:
+ case AnimateTypeDropFromTop:
+ tileSetNewWindowSize (w);
+ /* fall-through */
+ case AnimateTypeFade:
+ tw->animationType = Animating;
+ break;
+ default:
+ break;
+ }
+#endif
+ return true;
+}
+
+bool
+TileWindow::is ()
+{
+ TILE_SCREEN (screen);
+
+ if (ts->optionGetExcludeMatch ().evaluate (window))
+ return false;
+
+ if (window->overrideRedirect ())
+ return false;
+
+ if (!window->focus ())
+ return false;
+
+ if (window->wmType () & (CompWindowTypeDockMask | CompWindowTypeDesktopMask))
+ return false;
+
+ if (window->state () & CompWindowStateSkipPagerMask)
+ return false;
+
+ if (window->minimized () || !window->placed ())
+ return false;
+
+ return true;
+}
+
+Tiler::Tiler () :
+ state (Tiler::NotTiled),
+ maximized (false),
+ savedMaxState (0)
+{
+ TILE_SCREEN (screen);
+ ts->tilers.push_back(this);
+}
+
+void
+Tiler::save (CompWindow *w)
+{
+ saved.setGeometry (w->serverX (), w->serverY (),
+ w->serverWidth (), w->serverHeight ());
+
+ maximized = w->state () & MAXIMIZE_STATE;
+
+ savedMaxState = w->state () & MAXIMIZE_STATE;
+}
+
+bool
+Tiler::configure (CompWindow *w,
+ TileScreen::TileType type)
+{
+ XWindowChanges xwc;
+ unsigned int mask = CWX | CWY | CWWidth | CWHeight;
+ unsigned int xwidth, xheight;
+
+ TILE_WINDOW (w);
+
+ xwc.x = current.x ();
+ xwc.y = current.y ();
+ xwc.width = current.width ();
+ xwc.height = current.height ();
+
+ if (type == TileScreen::Restore)
+ {
+ if (maximized)
+ w->maximize (savedMaxState); // ???
+ }
+ else
+ w->maximize (0);
+
+ xwidth = xwc.width;
+ xheight = xwc.height;
+
+ if (xwidth == w->serverWidth ())
+ mask &= ~CWWidth;
+
+ if (xheight == w->serverHeight ())
+ mask &= ~CWHeight;
+
+ if (w->mapNum () && (mask & (CWWidth | CWHeight)))
+ w->sendSyncRequest ();
+
+ w->configureXWindow (mask, &xwc);
+ tw->needConfigure = false;
+
+ return true;
+}
+
+void
+TileScreen::restoreTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+ foreach (CompWindow *w, screen->windows ())
+ {
+ TILE_WINDOW (w);
+ if (tw->tiler)
+ {
+ tw->placeWin (tw->tiler->saved.x (), tw->tiler->saved.y (),
+ tw->tiler->saved.width (), tw->tiler->saved.height ());
+ tilers.remove (tw->tiler);
+ delete tw->tiler;
+ }
+ }
+}
+
+
+void
+TileScreen::squareTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+ int countX = ceil (sqrt (count));
+ int countY = ceil ((float)count / countX);
+ int currentX = workArea.x;
+ int currentY = workArea.y;
+ int winWidth = workArea.width / countX;
+ int winHeight = workArea.height / countY;
+ int i = 0;
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ TILE_WINDOW (w);
+ /* Put the window at the current slot */
+ tw->placeWin (currentX + border.left, currentY + border.top,
+ winWidth - (border.left + border.right),
+ winHeight - (border.top + border.bottom));
+
+ /* If we have reached countX ... */
+ if (!(i % countX))
+ {
+ /* Reset currentX back to the workArea start
+ * and move current Y
+ */
+ currentX = workArea.x;
+ currentY += winHeight;
+ }
+ /* Otherwise, add winWidth to currentX */
+ else
+ currentX += winWidth;
+ }
+}
+
+void
+TileScreen::horizontalTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+}
+
+void
+TileScreen::verticalTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+}
+
+/* Adapated from scale.c
+ * Copyright (c) 2007 Novell Inc.
+ */
+
+void
+TileScreen::evenTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+}
+
+/* Adapted from maximumize.c
+ * Copyright (c) 2007 Kristian Lyngstol
+ */
+
+void
+TileScreen::expandTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+}
+
+/* Adapted from presentwindows.cpp
+ * Copyright (c) 2007 Rivo Laks
+ * Copyright (c) 2008 Lucas Murray
+ */
+
+void
+TileScreen::organicTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+}
+
+void
+TileScreen::cascadeTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count)
+{
+}
+
+bool
+TileScreen::applyTiling (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options,
+ TileScreen::TileType type)
+{
+ int count = 0;
+ XRectangle workArea;
+ CompWindowExtents border;
+
+ workArea = screen->workArea ();
+ memset (&border, 0, sizeof (CompWindowExtents));
+
+ foreach (CompWindow *w, screen->windows ())
+ {
+ TILE_WINDOW (w);
+ /* Set the largest border size as some windows may be maximized */
+ if (tw->is ())
+ {
+ if (w->input ().left > border.left)
+ border.left = w->input ().left;
+ if (w->input ().right > border.right)
+ border.right = w->input ().right;
+ if (w->input ().top > border.top)
+ border.top = w->input ().top;
+ if (w->input ().bottom > border.bottom)
+ border.bottom = w->input ().bottom;
+
+ if (!tw->tiler)
+ tw->tiler = new Tiler;
+
+ count++;
+ }
+ }
+
+ /* TODO: Should probably be replaced by a propper extension manager */
+
+ switch (type)
+ {
+ case Restore:
+ restoreTile (border, workArea, count);
+ break;
+ case Square:
+ squareTile (border, workArea, count);
+ break;
+ case Even:
+ evenTile (border, workArea, count);
+ break;
+ case Horizontal:
+ horizontalTile (border, workArea, count);
+ break;
+ case Vertical:
+ verticalTile (border, workArea, count);
+ break;
+ case Expand:
+ expandTile (border, workArea, count);
+ break;
+ case Organic:
+ organicTile (border, workArea, count);
+ break;
+ case Cascade:
+ cascadeTile (border, workArea, count);
+ break;
+ }
+
+ return true;
+}
+
+#if 0
+/* Applies tiling/restoring */
+static bool
+applyTiling (CompScreen *s)
+{
+ CompWindow *w;
+ int count = 0;
+
+ TILE_SCREEN (s);
+
+ if (ts->grabIndex)
+ return false;
+
+ for (w = s->windows; w; w = w->next)
+ {
+ if (isTileWindow (w))
+ count++;
+ }
+
+ ts->oneDuration = tileGetAnimationDuration (s->display) / MAX (count, 1);
+
+ if (count > 1)
+ {
+ memset (&border, 0, sizeof (CompWindowExtents));
+ /* first get the largest border of the windows on this
+ screen - some of the windows in our list might be
+ maximized now and not be maximized later, so
+ their border information may be inaccurate */
+ for (w = s->windows; w; w = w->next)
+ {
+ if (w->input.left > border.left)
+ border.left = w->input.left;
+ if (w->input.right > border.right)
+ border.right = w->input.right;
+ if (w->input.top > border.top)
+ border.top = w->input.top;
+ if (w->input.bottom > border.bottom)
+ border.bottom = w->input.bottom;
+ }
+
+ workArea = s->workArea;
+
+ switch (ts->tileType)
+ {
+ case TileToggleTypeTile:
+
+ break;
+ case TileToggleTypeLeft:
+ height = workArea.height / (count - 1);
+ occupancy = tileGetTileLeftOccupancy (s->display);
+ break;
+ case TileToggleTypeTileVertically:
+ winWidth = workArea.width / count;
+ winHeight = workArea.height;
+ y = workArea.y;
+ break;
+ case TileToggleTypeTileHorizontally:
+ winWidth = workArea.width;
+ winHeight = workArea.height / count;
+ x = workArea.x;
+ break;
+ case TileToggleTypeCascade:
+ delta = tileGetTileDelta (s->display);
+ currentX = workArea.x;
+ currentY = workArea.y;
+ winHeight = workArea.height - delta * (count - 1);
+ winWidth = workArea.width - delta * (count - 1);
+ break;
+ default:
+ break;
+ }
+
+ for (w = s->windows; w; w = w->next)
+ {
+ if (!isTileWindow (w))
+ continue;
+
+ TILE_WINDOW (w);
+
+ if (!tw->savedValid)
+ saveCoords (w);
+
+ switch (ts->tileType)
+ {
+ case TileToggleTypeTile:
+ placeWin(w,
+ currentX + border.left, currentY + border.top,
+ winWidth - (border.left + border.right),
+ winHeight - (border.top + border.bottom));
+ tw->isTiled = true;
+ break;
+ case TileToggleTypeLeft:
+ if (first)
+ {
+ x = workArea.x;
+ y = workArea.y;
+ winWidth = workArea.width * occupancy / 100;
+ winHeight = workArea.height;
+ first = false;
+ }
+ else
+ {
+ x = workArea.x + (workArea.width * occupancy / 100);
+ y = workArea.y + (i * height);
+ winWidth = (workArea.width * (100 - occupancy) / 100);
+ winHeight = height;
+ }
+
+ placeWin(w,
+ x + border.left, y + border.top,
+ winWidth - (border.left + border.right),
+ winHeight - (border.top + border.bottom));
+ tw->isTiled = true;
+ break;
+ case TileToggleTypeTileVertically:
+ x = workArea.x + (winWidth * i);
+ placeWin(w,
+ x + border.left, y + border.top,
+ winWidth - (border.left + border.right),
+ winHeight - (border.top + border.bottom));
+ tw->isTiled = true;
+ break;
+ case TileToggleTypeTileHorizontally:
+ y = workArea.y + (winHeight * i);
+ placeWin (w, x + border.left, y + border.top,
+ winWidth - (border.left + border.right),
+ winHeight - (border.top + border.bottom));
+ tw->isTiled = true;
+ break;
+ case TileToggleTypeCascade:
+ placeWin (w,
+ currentX + border.left, currentY + border.top,
+ winWidth - (border.left + border.right),
+ winHeight - (border.top + border.bottom));
+ tw->isTiled = true;
+ break;
+ case -1:
+ if (tw->isTiled)
+ {
+ placeWin (w,
+ tw->savedCoords.x, tw->savedCoords.y,
+ tw->savedCoords.width, tw->savedCoords.height);
+ tw->savedValid = false;
+ tw->isTiled = false;; }
+ break;
+ default:
+ break;
+ }
+
+ i++;
+ tw->animationNum = i;
+
+ switch (ts->tileType)
+ {
+ case TileToggleTypeTile:
+ if (!(i % countX))
+ {
+ currentX = workArea.x;
+ currentY += winHeight;
+ }
+ else
+ currentX += winWidth;
+ break;
+ case TileToggleTypeCascade:
+ currentX += delta;
+ currentY += delta;
+ default:
+ break;
+ }
+ }
+
+ if (!ts->grabIndex)
+ ts->grabIndex = pushScreenGrab (s, s->invisibleCursor, "tile");
+
+ ts->msResizing = 0;
+ }
+
+ return true;
+}
+#endif
+
+TileScreen::TileScreen (CompScreen *screen) :
+ PrivateHandler <TileScreen, CompScreen> (screen),
+ TileOptions (tileVTable->getMetadata ()),
+ cScreen (CompositeScreen::get (screen)),
+ gScreen (GLScreen::get (screen)),
+ state (Normal),
+ time (0),
+ nextPosition (0, 0, 0, 0)
+{
+ ScreenInterface::setHandler (screen);
+ CompositeScreenInterface::setHandler (cScreen, false);
+ GLScreenInterface::setHandler (gScreen, false);
+
+#define tileInitiate(opt, type) \
+ optionSet##opt##Initiate (boost::bind (&TileScreen::applyTiling, this, \
+ _1, _2, _3, type))
+
+ tileInitiate (RestoreKey, Restore);
+ tileInitiate (SquareKey, Square);
+ tileInitiate (EvenKey, Restore);
+ tileInitiate (HorizontalKey, Restore);
+ tileInitiate (VerticalKey, Restore);
+ tileInitiate (ExpandKey, Restore);
+ tileInitiate (OrganicKey, Restore);
+ tileInitiate (CascadeKey, Restore);
+
+ tileInitiate (RestoreEdge, Restore);
+ tileInitiate (SquareEdge, Square);
+ tileInitiate (EvenEdge, Restore);
+ tileInitiate (HorizontalEdge, Restore);
+ tileInitiate (VerticalEdge, Restore);
+ tileInitiate (ExpandEdge, Restore);
+ tileInitiate (OrganicEdge, Restore);
+ tileInitiate (CascadeEdge, Restore);
+
+#undef tileInitiate
+}
+
+TileWindow::TileWindow (CompWindow *window) :
+ PrivateHandler <TileWindow, CompWindow> (window),
+ window (window),
+ gWindow (GLWindow::get (window)),
+ time (0),
+ alreadyResized (false),
+ needConfigure (false),
+ tiler (NULL)
+{
+ WindowInterface::setHandler (window, false);
+ GLWindowInterface::setHandler (gWindow, false);
+
+ for (int i = 0; i < 3; i++)
+ outlineColor[i] = 0;
+
+}
+
+TileWindow::~TileWindow ()
+{
+ if (tiler)
+ {
+ TILE_SCREEN (screen);
+ ts->tilers.remove (tiler);
+ delete tiler;
+ }
+}
+
+bool
+TilePluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
+ !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
+ !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
+ return false; /* should set 'animate' vars'*/
+
+ return true;
+}
diff --git a/tile.h b/tile.h
new file mode 100644
index 0000000..81a0e57
--- /dev/null
+++ b/tile.h
@@ -0,0 +1,255 @@
+/**
+ *
+ * Compiz tile plugin
+ *
+ * tile.c
+ *
+ * Copyright (c) 2006 Atie H. <atie.at.matrix@gmail.com>
+ * Copyright (c) 2006 Michal Fojtik <pichalsi(at)gmail.com>
+ * Copyright (c) 2007 Danny Baumann <maniac@beryl-project.org>
+ *
+ * Rewritten by:
+ * Copyright (c) 2008 Sam Spilsbury <smspillaz@gmail.com>
+ *
+ * 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
+ * of the License, 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.
+ *
+ * TODO
+ * - change vertical and horizontal tiling to similar behavior as Left
+ * - fix bugs
+ * - make vertical and horizontal maximization be saved when tiling
+ *
+ **/
+
+#include <core/core.h>
+#include <core/privatehandler.h>
+
+#include <composite/composite.h>
+#include <opengl/opengl.h>
+
+#include "tile_options.h"
+
+#include <cmath>
+
+class Tiler;
+
+class TileScreen :
+ public PrivateHandler <TileScreen, CompScreen>,
+ public TileOptions,
+ public ScreenInterface,
+ public CompositeScreenInterface,
+ public GLScreenInterface
+{
+ public:
+
+ typedef enum
+ {
+ Normal = 0,
+ In,
+ Tiled,
+ Out
+ } State;
+
+ typedef enum
+ {
+ Restore = 0,
+ Square,
+ Even,
+ Horizontal,
+ Vertical,
+ Expand,
+ Organic,
+ Cascade
+ } TileType;
+
+ public:
+
+ TileScreen (CompScreen *screen);
+
+ CompositeScreen *cScreen;
+ GLScreen *gScreen;
+
+ State state;
+ int time;
+
+ /* Tiling queue */
+
+ std::list <Tiler *> tilers;
+ CompRect nextPosition;
+ TileType type;
+
+ void
+ preparePaint (int);
+
+ /* finsih */
+
+ bool
+ glPaintOutput (const GLScreenPaintAttrib &attrib,
+ const GLMatrix &transform,
+ CompRegion &region,
+ CompOutput *output,
+ unsigned int mask);
+#if 0
+ bool
+ glPaintScreen (CompOutput *outputs,
+ int numOutputs,
+ unsigned int mask); //for ensuring fullscreen output;
+#endif
+ void
+ donePaint ();
+
+ /* Tiling modes */
+
+ void
+ restoreTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ void
+ squareTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ void
+ horizontalTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ void
+ verticalTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ void
+ evenTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ void
+ expandTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ void
+ organicTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ void
+ cascadeTile (CompWindowExtents &border,
+ XRectangle &workArea,
+ int count);
+
+ /* Actions */
+
+ bool
+ applyTiling (CompAction *action,
+ CompAction::State state,
+ CompOption::Vector options,
+ TileType type);
+};
+
+#define TILE_SCREEN(s) \
+ TileScreen *ts = TileScreen::get (s);
+
+class Tiler
+{
+ public:
+
+ Tiler ();
+
+ public:
+
+ typedef enum
+ {
+ NotTiled = 0,
+ WaitingForTile,
+ WaitingForRestore,
+ Tiled
+ } State;
+
+ public:
+
+ State state;
+
+ bool maximized;
+ int savedMaxState;
+
+ CompRect saved;
+ CompRect previous;
+ CompRect current;
+
+ bool
+ configure (CompWindow *,
+ TileScreen::TileType);
+
+ void
+ save (CompWindow *);
+};
+
+class TileWindow :
+ public PrivateHandler <TileWindow, CompWindow>,
+ public WindowInterface,
+ public GLWindowInterface
+{
+ public:
+
+ TileWindow (CompWindow *window);
+ ~TileWindow ();
+
+ CompWindow *window;
+ GLWindow *gWindow;
+
+ bool animate;
+
+ int outlineColor[3];
+ int time;
+
+ bool alreadyResized;
+ bool needConfigure;
+
+ Tiler *tiler;
+
+ void
+ resizeNotify (int, int, int, int);
+
+ bool
+ glPaint (const GLWindowPaintAttrib &attrib,
+ const GLMatrix &transform,
+ CompRegion &region,
+ unsigned int mask);
+
+ void
+ constrainMinMax (int width,
+ int height,
+ int &newWidth,
+ int &newHeight);
+
+ bool
+ placeWin (int x,
+ int y,
+ unsigned int width,
+ unsigned int height);
+
+ bool is ();
+};
+
+#define TILE_WINDOW(w) \
+ TileWindow *tw = TileWindow::get (w);
+
+class TilePluginVTable :
+ public CompPlugin::VTableForScreenAndWindow <TileScreen, TileWindow>
+{
+ public:
+
+ bool init ();
+
+ PLUGIN_OPTION_HELPER (TileScreen);
+};
diff --git a/tile.xml.in b/tile.xml.in
index 19ea3f4..90d8e31 100644
--- a/tile.xml.in
+++ b/tile.xml.in
@@ -4,7 +4,7 @@
<_short>Tile</_short>
<_long>Tile windows</_long>
<category>Window Management</category>
- <display>
+ <options>
<group>
<_short>Options</_short>
<option name="animate_type" type="int">
@@ -99,36 +99,72 @@
</group>
<group>
<_short>Key Bindings</_short>
- <option name="tile_vertically_key" type="key">
- <_short>Tile Windows Vertically</_short>
- <_long>Move and resize all visible windows so that they have full height, same width and occupy whole screen.</_long>
- </option>
- <option name="tile_horizontally_key" type="key">
- <_short>Tile Windows Horizontally</_short>
- <_long>Move and resize all visible windows so that they have full width, same height and occupy whole screen.</_long>
- </option>
- <option name="tile_tile_key" type="key">
- <_short>Tile Windows</_short>
- <_long>Move and resize all visible windows both vertically and horizontally, so that the occupy whole screen and are in a grid.</_long>
- <default>&lt;Super&gt;&lt;Shift&gt;a</default>
- </option>
- <option name="tile_cascade_key" type="key">
- <_short>Cascade Windows</_short>
- <_long>Move and resize all visible windows with the delta value set for cascading.</_long>
- <default>&lt;Super&gt;&lt;Shift&gt;s</default>
- </option>
- <option name="tile_restore_key" type="key">
- <_short>Restore Windows</_short>
- <_long>Restore windows to their original position they had before tiling.</_long>
- <default>&lt;Super&gt;&lt;Shift&gt;z</default>
- </option>
- <option name="tile_toggle_key" type="key">
- <_short>Toggle Tiling</_short>
- <_long>Toggle between tile and restore</_long>
- <default>&lt;Super&gt;&lt;Shift&gt;x</default>
+ <option name="restore_key" type="key">
+ <_short>Restore to previous position</_short>
+ <_long>Restore all windows to an untiled state</_long>
+ </option>
+ <option name="square_key" type="key">
+ <_short>Tile windows in a square pattern</_short>
+ <_long>Move and resize all windows so that they appear on screen in a square pattern</_long>
+ </option>
+ <option name="even_key" type="key">
+ <_short>Tile windows evenly</_short>
+ <_long>Move and resize all windows so that they are mostly the same size and take up all screen space</_long>
+ </option>
+ <option name="horizontal_key" type="key">
+ <_short>Tile windows in a horizontal pattern</_short>
+ <_long>Move and resize all windwos so that they appear on screen in a horizontal pattern</_long>
+ </option>
+ <option name="vertical_key" type="key">
+ <_short>Tile windows in a vertical pattern</_short>
+ <_long>Move and resize all windwos so that they appear on screen in a vertical pattern</_long>
+ </option>
+ <option name="expand_key" type="key">
+ <_short>Expand all windows</_short>
+ <_long>Move and resize all windows so that they stay in their current position as best as possible and expand to take up screen space</_long>
+ </option>
+ <option name="organic_key" type="key">
+ <_short>Make visible all windows</_short>
+ <_long>Move and resize all windows as little as possible to ensure that every one is visible</_long>
+ </option>
+ <option name="cascade_key" type="key">
+ <_short>Cascade windows</_short>
+ <_long>Move and resize all windows so they are in a cascading pattern with a specified distance between them</_long>
+ </option>
+ <option name="restore_edge" type="edge">
+ <_short>Restore to previous position</_short>
+ <_long>Restore all windows to an untiled state</_long>
+ </option>
+ <option name="square_edge" type="edge">
+ <_short>Tile windows in a square pattern</_short>
+ <_long>Move and resize all windows so that they appear on screen in a square pattern</_long>
+ </option>
+ <option name="even_edge" type="edge">
+ <_short>Tile windows evenly</_short>
+ <_long>Move and resize all windows so that they are mostly the same size and take up all screen space</_long>
+ </option>
+ <option name="horizontal_edge" type="edge">
+ <_short>Tile windows in a horizontal pattern</_short>
+ <_long>Move and resize all windwos so that they appear on screen in a horizontal pattern</_long>
+ </option>
+ <option name="vertical_edge" type="edge">
+ <_short>Tile windows in a vertical pattern</_short>
+ <_long>Move and resize all windwos so that they appear on screen in a vertical pattern</_long>
+ </option>
+ <option name="expand_edge" type="edge">
+ <_short>Expand all windows</_short>
+ <_long>Move and resize all windows so that they stay in their current position as best as possible and expand to take up screen space</_long>
+ </option>
+ <option name="organic_edge" type="edge">
+ <_short>Make visible all windows</_short>
+ <_long>Move and resize all windows as little as possible to ensure that every one is visible</_long>
+ </option>
+ <option name="cascade_edge" type="edge">
+ <_short>Cascade windows</_short>
+ <_long>Move and resize all windows so they are in a cascading pattern with a specified distance between them</_long>
</option>
</group>
- </display>
+ </options>
</plugin>
</compiz>