#include "group.h" /** * * Beryl group plugin * * init.c * * Copyright : (C) 2006 by Patrick Niklaus, Roi Cohen, Danny Baumann * Authors: Patrick Niklaus * Roi Cohen * Danny Baumann * * * 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. * **/ #define UPDATE_TAB_BAR_INTERVAL 200 /* * groupInitDisplay * */ Bool groupInitDisplay(CompPlugin * p, CompDisplay * d) { GroupDisplay *gd; gd = malloc(sizeof(GroupDisplay)); if (!gd) return FALSE; gd->screenPrivateIndex = allocateScreenPrivateIndex(d); if (gd->screenPrivateIndex < 0) { free(gd); return FALSE; } gd->tmpSel.windows = NULL; gd->tmpSel.nWins = 0; //gd->revGroups = NULL; gd->ignoreMode = FALSE; groupDisplayInitOptions(gd); WRAP(gd, d, handleEvent, groupHandleEvent); gd->timeoutHandle = compAddTimeout (UPDATE_TAB_BAR_INTERVAL, groupUpdateTabBars, d); d->privates[displayPrivateIndex].ptr = gd; return TRUE; } /* * groupFiniDisplay * */ void groupFiniDisplay(CompPlugin * p, CompDisplay * d) { GROUP_DISPLAY(d); freeScreenPrivateIndex(d, gd->screenPrivateIndex); UNWRAP(gd, d, handleEvent); compRemoveTimeout(gd->timeoutHandle); free(gd); } /* * groupInitScreen * */ Bool groupInitScreen(CompPlugin * p, CompScreen * s) { GroupScreen *gs; GROUP_DISPLAY(s->display); gs = malloc(sizeof(GroupScreen)); if (!gs) return FALSE; gs->windowPrivateIndex = allocateWindowPrivateIndex(s); if (gs->windowPrivateIndex < 0) { free(gs); return FALSE; } groupScreenInitOptions(gs); gs->wMask=compWindowTypeMaskFromStringList(&gs->opt[GROUP_SCREEN_OPTION_TYPES].value); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_SELECT].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_SELECT_SINGLE].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_GROUPING].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_UNGROUPING].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_REMOVING].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CLOSING].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_IGNORE].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CHANGE_COLOR].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_TABMODE].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CHANGE_TAB_LEFT].value.action); addScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CHANGE_TAB_RIGHT].value.action); WRAP(gs, s, windowMoveNotify, groupWindowMoveNotify); WRAP(gs, s, windowResizeNotify, groupWindowResizeNotify); WRAP(gs, s, getOutputExtentsForWindow, groupGetOutputExtentsForWindow); WRAP(gs, s, preparePaintScreen, groupPreparePaintScreen); WRAP(gs, s, paintScreen, groupPaintScreen); WRAP(gs, s, drawWindow, groupDrawWindow); WRAP(gs, s, paintWindow, groupPaintWindow); WRAP(gs, s, paintTransformedScreen, groupPaintTransformedScreen); WRAP(gs, s, donePaintScreen, groupDonePaintScreen); WRAP(gs, s, windowGrabNotify, groupWindowGrabNotify); WRAP(gs, s, windowUngrabNotify, groupWindowUngrabNotify); WRAP(gs,s,damageWindowRect,groupDamageWindowRect); WRAP(gs,s,windowStateChangeNotify,groupWindowStateChangeNotify); s->privates[gd->screenPrivateIndex].ptr = gs; gs->groups = NULL; gs->grabIndex = 0; gs->grabState = ScreenGrabNone; gs->queued = FALSE; gs->tabBarVisible = FALSE; gs->pendingMoves = NULL; gs->pendingGrabs = NULL; gs->pendingUngrabs = NULL; gs->draggedSlot = NULL; gs->dragged = FALSE; gs->dragHoverTimeoutHandle = 0; gs->prevX = 0; gs->prevY = 0; gs->isRotating = FALSE; /* gs->glowType is already initialized in groupScreenInitOptions */ initTexture (s, &gs->glowTexture); RGBAimageToTexture (s, &gs->glowTexture, glowTextureProperties[gs->glowType].textureData, glowTextureProperties[gs->glowType].textureSize, glowTextureProperties[gs->glowType].textureSize); return TRUE; } /* * groupFiniScreen * */ void groupFiniScreen(CompPlugin * p, CompScreen * s) { GROUP_SCREEN(s); GROUP_DISPLAY(s->display); if (gs->groups) { GroupSelection *group, *next_group; for(group = gs->groups; group;) { if (group->tabBar) { GroupTabBarSlot *slot, *next_slot; for (slot = group->tabBar->slots; slot;) { if (slot->region) XDestroyRegion(slot->region); if (slot->name) free(slot->name); next_slot = slot->next; free(slot); slot = next_slot; } groupDestroyCairoLayer(group->screen, group->tabBar->textLayer); groupDestroyCairoLayer(group->screen, group->tabBar->bgLayer); groupDestroyCairoLayer(group->screen, group->tabBar->selectionLayer); if (group->inputPrevention) XDestroyWindow(s->display->display, group->inputPrevention); if (group->tabBar->region) XDestroyRegion(group->tabBar->region); free(group->tabBar); } next_group = group->next; free(group); group = next_group; } } freeWindowPrivateIndex(s, gs->windowPrivateIndex); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_SELECT].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_SELECT_SINGLE].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_GROUPING].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_UNGROUPING].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_REMOVING].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CLOSING].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_IGNORE].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CHANGE_COLOR].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_TABMODE].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CHANGE_TAB_LEFT].value.action); removeScreenAction(s, &gd->opt[GROUP_DISPLAY_OPTION_CHANGE_TAB_RIGHT].value.action); UNWRAP(gs, s, windowMoveNotify); UNWRAP(gs, s, windowResizeNotify); UNWRAP(gs, s, getOutputExtentsForWindow); UNWRAP(gs, s, preparePaintScreen); UNWRAP(gs, s, paintScreen); UNWRAP(gs, s, drawWindow); UNWRAP(gs, s, paintWindow); UNWRAP(gs, s, paintTransformedScreen); UNWRAP(gs, s, donePaintScreen); UNWRAP(gs, s, windowGrabNotify); UNWRAP(gs, s, windowUngrabNotify); UNWRAP(gs,s,damageWindowRect); UNWRAP(gs,s,windowStateChangeNotify); finiTexture (s, &gs->glowTexture); free(gs); } /* * groupInitWindow * */ Bool groupInitWindow(CompPlugin * p, CompWindow * w) { GroupWindow *gw; GROUP_SCREEN(w->screen); gw = malloc(sizeof(GroupWindow)); if (!gw) return FALSE; gw->group = NULL; gw->inSelection = FALSE; gw->needsPosSync = FALSE; // for tab gw->oldWindowState = getWindowState(w->screen->display, w->id); gw->animateState = 0; gw->ungroup = FALSE; gw->slot = NULL; gw->tx = gw->ty = 0; gw->xVelocity = gw->yVelocity = 0; gw->orgPos.x = 0; gw->orgPos.y = 0; gw->mainTabOffset.x = 0; gw->mainTabOffset.y = 0; gw->destination.x = 0; gw->destination.y = 0; if (w->minimized) gw->windowState = WindowMinimized; else if (w->shaded) gw->windowState = WindowShaded; else gw->windowState = WindowNormal; gw->lastState = w->state; //gw->offscreen = FALSE; w->privates[gs->windowPrivateIndex].ptr = gw; gw->glowQuads = NULL; groupComputeGlowQuads (w, &gs->glowTexture.matrix); return TRUE; } /* * groupFiniWindow * */ void groupFiniWindow(CompPlugin * p, CompWindow * w) { GROUP_WINDOW(w); /* TODO: this needs more work; positioning is not correct at the moment - but it's way better than leaving the window offscreen */ if (gw->group && gw->group->tabBar && !IS_TOP_TAB(w, gw->group)) moveWindowOnscreen(w); if (gw->glowQuads) free (gw->glowQuads); free(gw); } /* * groupInit * */ Bool groupInit(CompPlugin * p) { displayPrivateIndex = allocateDisplayPrivateIndex(); if (displayPrivateIndex < 0) return FALSE; return TRUE; } /* * groupFini * */ void groupFini(CompPlugin * p) { if (displayPrivateIndex >= 0) freeDisplayPrivateIndex(displayPrivateIndex); } /* * groupDeps array * */ static CompPluginDep groupDeps[] = { {CompPluginRuleAfter, "place"}, }; static GroupDesc groupGroupDescs[] = { {"General", N_("General options"), NULL, 0}, {"Selection", N_("Options for the window selection"), NULL, 0}, {"Tabbing", N_("Options for window tabbing"), NULL, 0}, {"Glow", N_("Configuration options for the window glow"), NULL, 0} }; /* * groupVTable * */ CompPluginVTable groupVTable = { "group", N_("Group and Tab Windows"), N_("With this plugin you can group and tab windows."), groupInit, groupFini, groupInitDisplay, groupFiniDisplay, groupInitScreen, groupFiniScreen, groupInitWindow, groupFiniWindow, groupGetDisplayOptions, groupSetDisplayOption, groupGetScreenOptions, groupSetScreenOption, groupDeps, sizeof(groupDeps) / sizeof(groupDeps[0]), 0, 0, BERYL_ABI_INFO, "beryl-plugins-unsupported", "wm", groupGroupDescs, sizeof(groupGroupDescs) / sizeof(groupGroupDescs[0]), True, /* enabled by default */ }; /* * getCompPluginInfo * */ CompPluginVTable *getCompPluginInfo(void) { return &groupVTable; }