]> git.pld-linux.org Git - packages/compiz.git/blob - compiz-minimize-scaler-mod.patch
- 20060602
[packages/compiz.git] / compiz-minimize-scaler-mod.patch
1 Index: plugins/minimize.c
2 ===================================================================
3 RCS file: /cvs/xorg/app/compiz/plugins/minimize.c,v
4 retrieving revision 1.3
5 diff -u -r1.3 minimize.c
6 --- plugins/minimize.c  31 Mar 2006 11:22:34 -0000      1.3
7 +++ plugins/minimize.c  1 Apr 2006 16:20:55 -0000
8 @@ -26,6 +26,7 @@
9  #include <X11/Xatom.h>
10  
11  #include <stdlib.h>
12 +#include <stdio.h>
13  #include <string.h>
14  #include <math.h>
15  
16 @@ -41,6 +42,8 @@
17  #define MIN_TIMESTEP_MAX       50.0f
18  #define MIN_TIMESTEP_PRECISION 0.1f
19  
20 +#define FAKE_ICON_SIZE         4
21 +
22  static char *winType[] = {
23      "Toolbar",
24      "Utility",
25 @@ -61,7 +64,9 @@
26  #define MIN_SCREEN_OPTION_SPEED       0
27  #define MIN_SCREEN_OPTION_TIMESTEP    1
28  #define MIN_SCREEN_OPTION_WINDOW_TYPE 2
29 -#define MIN_SCREEN_OPTION_NUM         3
30 +#define MIN_SCREEN_OPTION_ON_CREATE   3
31 +#define MIN_SCREEN_OPTION_CENTER      4
32 +#define MIN_SCREEN_OPTION_NUM         5
33  
34  typedef struct _MinScreen {
35      int        windowPrivateIndex;
36 @@ -81,6 +86,8 @@
37      unsigned int wMask;
38  
39      int moreAdjust;
40 +    Bool scaleInNewWindows;
41 +    Bool scaleFromCenter;
42  } MinScreen;
43  
44  typedef struct _MinWindow {
45 @@ -95,6 +102,7 @@
46      int state, newState;
47  
48      int unmapCnt;
49 +    int destroyCnt;
50  } MinWindow;
51  
52  #define GET_MIN_DISPLAY(d)                                 \
53 @@ -119,6 +127,23 @@
54  
55  #define NUM_OPTIONS(s) (sizeof ((s)->opt) / sizeof (CompOption))
56  
57 +static Bool
58 +getMousePointerXY(CompScreen *s, short *x, short *y)
59 +{
60 +    Window w1, w2;
61 +    int xp, yp, xj, yj;
62 +    unsigned int m;
63 +    
64 +    if (XQueryPointer (s->display->display, s->root, &w1, &w2, &xj, &yj, &xp, &yp, &m))
65 +    {
66 +        *x = xp;
67 +        *y = yp;
68 +        return TRUE;
69 +    }
70 +    
71 +    return FALSE;
72 +}
73 +
74  static CompOption *
75  minGetScreenOptions (CompScreen *screen,
76                      int        *count)
77 @@ -164,6 +189,19 @@
78             ms->wMask = compWindowTypeMaskFromStringList (&o->value);
79             return TRUE;
80         }
81 +       break;
82 +    case MIN_SCREEN_OPTION_ON_CREATE:
83 +       if (compSetBoolOption (o, value))
84 +       {
85 +           ms->scaleInNewWindows = o->value.b;
86 +           return TRUE;
87 +       }
88 +    case MIN_SCREEN_OPTION_CENTER:
89 +       if (compSetBoolOption (o, value))
90 +       {
91 +           ms->scaleFromCenter = o->value.b;
92 +           return TRUE;
93 +       }
94      default:
95         break;
96      }
97 @@ -210,8 +248,22 @@
98         o->value.list.value[i].s = strdup (winType[i]);
99      o->rest.s.string     = windowTypeString;
100      o->rest.s.nString    = nWindowTypeString;
101 -
102      ms->wMask = compWindowTypeMaskFromStringList (&o->value);
103 +
104 +    o = &ms->opt[MIN_SCREEN_OPTION_ON_CREATE];
105 +    o->name      = "zoom_created_windows";
106 +    o->shortDesc = "Zoom Created Windows";
107 +    o->longDesc  = "Zooms created windows in from cursor/center";
108 +    o->type      = CompOptionTypeBool;
109 +    o->value.b   = TRUE;
110 +    
111 +    o = &ms->opt[MIN_SCREEN_OPTION_CENTER];
112 +    o->name      = "zoom_created_windows_from_center";
113 +    o->shortDesc = "Zoom Created Windows from Center";
114 +    o->longDesc  = "Zooms created windows in from center instead of cursor";
115 +    o->type      = CompOptionTypeBool;
116 +    o->value.b   = FALSE;
117 +
118  }
119  
120  static Bool
121 @@ -286,7 +338,7 @@
122  
123      MIN_WINDOW (w);
124  
125 -    if (mw->newState == IconicState)
126 +    if (mw->newState == IconicState || mw->newState == WithdrawnState)
127      {
128         x1 = mw->icon.x;
129         y1 = mw->icon.y;
130 @@ -357,6 +409,11 @@
131         mw->ty = y1 - w->attrib.y;
132         mw->xScale = xScale;
133         mw->yScale = yScale;
134 +       if (mw->destroyCnt)
135 +       {
136 +           destroyWindow (w);
137 +           mw->destroyCnt--;
138 +       }
139  
140         return 0;
141      }
142 @@ -531,6 +588,21 @@
143             }
144         }
145         break;
146 +    case DestroyNotify:
147 +        w = findWindowAtDisplay (d, event->xunmap.window);
148 +        /* mark it for zooming out */
149 +        if (w)
150 +        {
151 +            MIN_SCREEN (w->screen);
152 +            if (ms->wMask & w->type)
153 +            {
154 +                MIN_WINDOW(w);
155 +                mw->destroyCnt++;
156 +                w->destroyRefCnt++;
157 +                addWindowDamage(w);
158 +            }
159 +        }
160 +        break;
161      case UnmapNotify:
162         w = findWindowAtDisplay (d, event->xunmap.window);
163         if (w)
164 @@ -564,13 +636,39 @@
165             else  /* X -> Withdrawn */
166             {
167                 MIN_WINDOW (w);
168 -
169 -               if (mw->state == IconicState)
170 -               {
171 -                   (*w->screen->setWindowScale) (w, 1.0f, 1.0f);
172 -                   mw->state = NormalState;
173 -               }
174 -           }
175 +                if (ms->wMask & w->type)
176 +                {
177 +                     if (mw->state == IconicState)
178 +                     {
179 +                          (*w->screen->setWindowScale) (w, 1.0f, 1.0f);
180 +                     }
181 +                      
182 +                      mw->state = NormalState;
183 +                      mw->newState = WithdrawnState;
184 +                      
185 +                      /* let's zoom windows on hide */
186 +                      if (getMousePointerXY (w->screen, &mw->icon.x, &mw->icon.y) &&
187 +                          ms->scaleInNewWindows && (ms->wMask & w->type))
188 +                      {
189 +                          mw->icon.width = FAKE_ICON_SIZE;
190 +                          mw->icon.height = FAKE_ICON_SIZE;
191 +                          mw->icon.x -= FAKE_ICON_SIZE/2;
192 +                          mw->icon.y -= FAKE_ICON_SIZE/2;
193 +                          
194 +                          if (ms->scaleFromCenter)
195 +                          {
196 +                              mw->icon.x = w->attrib.x + w->attrib.width/2 - FAKE_ICON_SIZE/2;
197 +                              mw->icon.y = w->attrib.y + w->attrib.height/2 - FAKE_ICON_SIZE/2;
198 +                          }
199 +                          
200 +                          mw->adjust = TRUE;
201 +                          ms->moreAdjust = TRUE;
202 +                          mw->unmapCnt++;
203 +                          w->unmapRefCnt++;
204 +                          addWindowDamage (w);
205 +                      }
206 +                }
207 +            }
208         }
209      default:
210         break;
211 @@ -630,6 +728,33 @@
212                 (*w->screen->setWindowScale) (w, 1.0f, 1.0f);
213             }
214         }
215 +        else if (mw->state != NormalState)
216 +        {
217 +            if (getMousePointerXY(w->screen,&mw->icon.x,&mw->icon.y) && ms->scaleInNewWindows)
218 +            {
219 +                mw->icon.width  = FAKE_ICON_SIZE;
220 +                mw->icon.height = FAKE_ICON_SIZE;
221 +                mw->icon.x -= FAKE_ICON_SIZE/2;
222 +                mw->icon.y -= FAKE_ICON_SIZE/2;
223 +                
224 +                if (ms->scaleFromCenter)
225 +                {
226 +                    mw->icon.x = w->attrib.x + w->attrib.width/2  - FAKE_ICON_SIZE/2;
227 +                    mw->icon.y = w->attrib.y + w->attrib.height/2 - FAKE_ICON_SIZE/2;
228 +                }
229 +                
230 +                mw->tx = mw->icon.x-w->attrib.x;
231 +                mw->ty = mw->icon.y-w->attrib.y;
232 +                mw->xScale = ((float)FAKE_ICON_SIZE) / w->attrib.width;
233 +                mw->yScale = ((float)FAKE_ICON_SIZE) / w->attrib.height;
234 +                
235 +                mw->state = IconicState; /* we're doing this as a hack, it may not be necessary */
236 +                mw->newState = NormalState;
237 +                mw->adjust = TRUE;
238 +                ms->moreAdjust = TRUE;
239 +                addWindowDamage (w);
240 +            }
241 +        }
242  
243         mw->newState = NormalState;
244      }
245 @@ -649,7 +774,7 @@
246      MIN_SCREEN (w->screen);
247      MIN_WINDOW (w);
248  
249 -    if (mw->unmapCnt)
250 +    if (mw->unmapCnt || mw->destroyCnt)
251         return FALSE;
252  
253      UNWRAP (ms, w->screen, focusWindow);
254 @@ -723,6 +848,8 @@
255  
256      ms->speed    = MIN_SPEED_DEFAULT;
257      ms->timestep = MIN_TIMESTEP_DEFAULT;
258 +    ms->scaleInNewWindows = TRUE;
259 +    ms->scaleFromCenter   = FALSE;
260  
261      minScreenInitOptions (ms);
262  
263 @@ -775,11 +902,40 @@
264      mw->xScaleVelocity = mw->yScaleVelocity = 1.0f;
265  
266      mw->unmapCnt = 0;
267 +    mw->destroyCnt = 0;
268  
269      mw->state = mw->newState = minGetWindowState (w);
270  
271      w->privates[ms->windowPrivateIndex].ptr = mw;
272  
273 +    /* use a 'virtual' icon of 32x32 at mpx-16,mpy-16 */
274 +    /* TODO consider changing this to a configurable thing somehow */
275 +    if (w->type & ms->wMask && ms->scaleInNewWindows && mw->state == NormalState)
276 +    {
277 +        if (getMousePointerXY (w->screen, &mw->icon.x, &mw->icon.y))
278 +        {
279 +            mw->icon.width = FAKE_ICON_SIZE;
280 +            mw->icon.height = FAKE_ICON_SIZE;
281 +            mw->icon.x -= FAKE_ICON_SIZE / 2;
282 +            mw->icon.y -= FAKE_ICON_SIZE / 2;
283 +            if (ms->scaleFromCenter)
284 +            {
285 +                mw->icon.x = w->attrib.x + w->attrib.width/2 - FAKE_ICON_SIZE/2;
286 +                mw->icon.y = w->attrib.y + w->attrib.height/2 - FAKE_ICON_SIZE/2;
287 +            }
288 +            
289 +            mw->tx = mw->icon.x - w->attrib.x;
290 +            mw->ty = mw->icon.y - w->attrib.y;
291 +            mw->xScale = ((float)FAKE_ICON_SIZE) / w->attrib.width;
292 +            mw->yScale = ((float)FAKE_ICON_SIZE) / w->attrib.height;
293 +            mw->state = IconicState; /* we're doing this as a hack, it may not be necessary */
294 +            mw->newState = NormalState;
295 +            mw->adjust=TRUE;
296 +            ms->moreAdjust=TRUE;
297 +            addWindowDamage (w);
298 +        }
299 +    }
300 +
301      return TRUE;
302  }
303  
This page took 0.094792 seconds and 3 git commands to generate.