~ubuntu-branches/ubuntu/oneiric/unity/oneiric

« back to all changes in this revision

Viewing changes to .pc/debian-changes-4.14.2-0ubuntu2/plugins/unityshell/src/compizminimizedwindowhandler.h

  • Committer: Package Import Robot
  • Author(s): Didier Roche
  • Date: 2011-09-12 08:12:54 UTC
  • Revision ID: package-import@ubuntu.com-20110912081254-qtz600pc32fva88o
Tags: 4.14.2-0ubuntu2
* Cherry-pick a fix for remapping minimized window correctly (LP: #840285)
* debian/control:
  - bump build-dep for latest compiz-dev ABI break

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
 
2
/*
 
3
 * Copyright (C) 2011 Canonical Ltd.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
 *
 
19
 * Authored By:
 
20
 * Sam Spilsbury <sam.spilsbury@canonical.com>
 
21
 */
 
22
 
 
23
#ifndef _COMPIZ_COMPIZMINIMIZEDWINDOWHANDLER_H
 
24
#define _COMPIZ_COMPIZMINIMIZEDWINDOWHANDLER_H
 
25
 
 
26
#include <core/core.h>
 
27
#include "minimizedwindowhandler.h"
 
28
#include "comptransientfor.h"
 
29
 
 
30
// Will be merged back into compiz
 
31
namespace compiz {
 
32
 
 
33
class PrivateCompizMinimizedWindowHandler
 
34
{
 
35
public:
 
36
 
 
37
  PrivateCompizMinimizedWindowHandler () {};
 
38
 
 
39
  CompWindow         *mWindow;
 
40
  WindowInputRemover *clientInputRemover;
 
41
};
 
42
 
 
43
template <typename Screen, typename Window>
 
44
class CompizMinimizedWindowHandler:
 
45
    public MinimizedWindowHandler
 
46
{
 
47
public:
 
48
 
 
49
  CompizMinimizedWindowHandler (CompWindow *w);
 
50
 
 
51
  void setVisibility (bool visible);
 
52
  unsigned int getPaintMask ();
 
53
 
 
54
  void minimize ();
 
55
  void unminimize ();
 
56
 
 
57
  void updateFrameRegion (CompRegion &r);
 
58
 
 
59
  static void setFunctions (bool keepMinimized);
 
60
  static void handleCompizEvent (const char *, const char *, CompOption::Vector &);
 
61
  static void handleEvent (XEvent *event);
 
62
  static std::list<CompWindow *> minimizingWindows;
 
63
 
 
64
  typedef CompizMinimizedWindowHandler<Screen, Window> CompizMinimizedWindowHandler_complete;
 
65
  typedef boost::shared_ptr<CompizMinimizedWindowHandler_complete> Ptr;
 
66
protected:
 
67
 
 
68
  virtual std::vector<unsigned int> getTransients ();
 
69
 
 
70
private:
 
71
 
 
72
  PrivateCompizMinimizedWindowHandler *priv;
 
73
  static bool handleEvents;
 
74
};
 
75
}
 
76
 
 
77
template <typename Screen, typename Window>
 
78
CompWindowList compiz::CompizMinimizedWindowHandler<Screen, Window>::minimizingWindows;
 
79
 
 
80
template <typename Screen, typename Window>
 
81
bool compiz::CompizMinimizedWindowHandler<Screen, Window>::handleEvents = true;
 
82
 
 
83
template <typename Screen, typename Window>
 
84
compiz::CompizMinimizedWindowHandler<Screen, Window>::CompizMinimizedWindowHandler(CompWindow *w) :
 
85
  MinimizedWindowHandler (screen->dpy (), w->id ())
 
86
{
 
87
  priv = new PrivateCompizMinimizedWindowHandler ();
 
88
 
 
89
  priv->mWindow = w;
 
90
  priv->clientInputRemover = NULL;
 
91
 
 
92
}
 
93
 
 
94
template <typename Screen, typename Window>
 
95
std::vector<unsigned int>
 
96
compiz::CompizMinimizedWindowHandler<Screen, Window>::getTransients ()
 
97
{
 
98
  std::vector <unsigned int> transients;
 
99
 
 
100
  for (CompWindow *w : screen->windows ())
 
101
  {
 
102
    compiz::CompTransientForReader *reader = new compiz::CompTransientForReader (w);
 
103
 
 
104
    if (reader->isTransientFor (priv->mWindow->id ()) ||
 
105
        reader->isGroupTransientFor (priv->mWindow->id ()))
 
106
      transients.push_back (w->id ());
 
107
 
 
108
    delete reader;
 
109
  }
 
110
 
 
111
  return transients;
 
112
}
 
113
 
 
114
template <typename Screen, typename Window>
 
115
void
 
116
compiz::CompizMinimizedWindowHandler<Screen, Window>::setVisibility (bool visible)
 
117
{
 
118
  CompWindow::Geometry gm = priv->mWindow->geometry ();
 
119
  MinimizedWindowHandler::setVisibility (visible, ROOTPARENT (priv->mWindow));
 
120
 
 
121
  if (!visible && !priv->clientInputRemover)
 
122
  {
 
123
    priv->clientInputRemover = new compiz::WindowInputRemover (screen->dpy (), priv->mWindow->id ());
 
124
    if (!priv->clientInputRemover)
 
125
      return;
 
126
 
 
127
    if (priv->clientInputRemover->save ())
 
128
      priv->clientInputRemover->remove ();
 
129
  }
 
130
  else if (visible && priv->clientInputRemover)
 
131
  {
 
132
    priv->clientInputRemover->restore ();
 
133
 
 
134
    delete priv->clientInputRemover;
 
135
    priv->clientInputRemover = NULL;
 
136
  }
 
137
 
 
138
  /* This is a little hack to ensure that the window region gets updated,
 
139
   * because there's no API in core to do that */
 
140
 
 
141
  gm.setBorder (gm.border () + 1);
 
142
  priv->mWindow->resize (gm);
 
143
  gm.setBorder (gm.border () - 1);
 
144
  priv->mWindow->resize (gm);
 
145
 
 
146
  CompositeWindow::get (priv->mWindow)->addDamage ();
 
147
  GLWindow::get (priv->mWindow)->glPaintSetEnabled (Window::get (priv->mWindow), !visible);
 
148
}
 
149
 
 
150
template <typename Screen, typename Window>
 
151
void
 
152
compiz::CompizMinimizedWindowHandler<Screen, Window>::minimize ()
 
153
{
 
154
  Atom          wmState = XInternAtom (screen->dpy (), "WM_STATE", 0);
 
155
  unsigned long data[2];
 
156
 
 
157
  std::vector<unsigned int> transients = getTransients ();
 
158
 
 
159
  handleEvents = true;
 
160
  priv->mWindow->windowNotify (CompWindowNotifyMinimize);
 
161
  priv->mWindow->changeState (priv->mWindow->state () | CompWindowStateHiddenMask);
 
162
 
 
163
  for (unsigned int &w : transients)
 
164
  {
 
165
    CompWindow *win = screen->findWindow (w);
 
166
 
 
167
    Window::get (win)->mMinimizeHandler = MinimizedWindowHandler::Ptr (new CompizMinimizedWindowHandler (win));
 
168
    Window::get (win)->minimize ();
 
169
  }
 
170
 
 
171
  priv->mWindow->windowNotify (CompWindowNotifyHide);
 
172
  setVisibility (false);
 
173
 
 
174
  data[0] = IconicState;
 
175
  data[1] = None;
 
176
 
 
177
  XChangeProperty (screen->dpy (), priv->mWindow->id (), wmState, wmState,
 
178
                   32, PropModeReplace, (unsigned char *) data, 2);
 
179
 
 
180
  priv->mWindow->changeState (priv->mWindow->state () | CompWindowStateHiddenMask);
 
181
  priv->mWindow->moveInputFocusToOtherWindow ();
 
182
}
 
183
 
 
184
template <typename Screen, typename Window>
 
185
void
 
186
compiz::CompizMinimizedWindowHandler<Screen, Window>::updateFrameRegion (CompRegion &r)
 
187
{
 
188
  unsigned int oldUpdateFrameRegionIndex;
 
189
  r -= infiniteRegion;
 
190
 
 
191
  /* Ensure no other plugins can touch this frame region */
 
192
  oldUpdateFrameRegionIndex = priv->mWindow->updateFrameRegionGetCurrentIndex ();
 
193
  priv->mWindow->updateFrameRegionSetCurrentIndex (MAXSHORT);
 
194
  priv->mWindow->updateFrameRegion (r);
 
195
  priv->mWindow->updateFrameRegionSetCurrentIndex (oldUpdateFrameRegionIndex);
 
196
}
 
197
 
 
198
template <typename Screen, typename Window>
 
199
void
 
200
compiz::CompizMinimizedWindowHandler<Screen, Window>::unminimize ()
 
201
{
 
202
  Atom          wmState = XInternAtom (screen->dpy (), "WM_STATE", 0);
 
203
  unsigned long data[2];
 
204
 
 
205
  std::vector<unsigned int> transients = getTransients ();
 
206
 
 
207
  priv->mWindow->windowNotify (CompWindowNotifyUnminimize);
 
208
  priv->mWindow->changeState (priv->mWindow->state () & ~CompWindowStateHiddenMask);
 
209
  priv->mWindow->windowNotify (CompWindowNotifyShow);
 
210
 
 
211
  for (unsigned int &w : transients)
 
212
  {
 
213
    CompWindow *win = screen->findWindow (w);
 
214
 
 
215
    if (Window::get (win)->mMinimizeHandler)
 
216
      Window::get (win)->mMinimizeHandler->unminimize ();
 
217
 
 
218
    Window::get (win)->mMinimizeHandler.reset ();
 
219
  }
 
220
 
 
221
  setVisibility (true);
 
222
 
 
223
  priv->mWindow->changeState (priv->mWindow->state () & ~CompWindowStateHiddenMask);
 
224
 
 
225
  data[0] = NormalState;
 
226
  data[1] = None;
 
227
 
 
228
  XChangeProperty (screen->dpy (), priv->mWindow->id (), wmState, wmState,
 
229
                   32, PropModeReplace, (unsigned char *) data, 2);
 
230
}
 
231
 
 
232
template <typename Screen, typename Window>
 
233
unsigned int
 
234
compiz::CompizMinimizedWindowHandler<Screen, Window>::getPaintMask ()
 
235
{
 
236
  bool doMask = true;
 
237
 
 
238
  for (CompWindow *w : minimizingWindows)
 
239
  {
 
240
    if (w->id () == priv->mWindow->id ())
 
241
      doMask = false;
 
242
    break;
 
243
  }
 
244
 
 
245
  if (doMask)
 
246
    return PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
 
247
 
 
248
  return 0;
 
249
}
 
250
 
 
251
template <typename Screen, typename Window>
 
252
void
 
253
compiz::CompizMinimizedWindowHandler<Screen, Window>::handleCompizEvent (const char *pluginName,
 
254
                                                                         const char *eventName,
 
255
                                                                         CompOption::Vector &o)
 
256
{
 
257
  if (!handleEvents)
 
258
    return;
 
259
 
 
260
  if (strncmp (pluginName, "animation", 9) == 0 &&
 
261
      strncmp (eventName, "window_animation", 16) == 0)
 
262
  {
 
263
    if (CompOption::getStringOptionNamed (o, "type", "") == "minimize")
 
264
    {
 
265
      CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (
 
266
                                            o, "window", 0));
 
267
      if (w)
 
268
      {
 
269
        if (CompOption::getBoolOptionNamed (o, "active", false))
 
270
          minimizingWindows.push_back (w);
 
271
        else
 
272
          minimizingWindows.remove (w);
 
273
      }
 
274
    }
 
275
  }
 
276
 
 
277
  if (!CompOption::getBoolOptionNamed (o, "active", false) &&
 
278
      minimizingWindows.empty ())
 
279
  {
 
280
    handleEvents = false;
 
281
  }
 
282
}
 
283
 
 
284
template <typename Screen, typename Window>
 
285
void
 
286
compiz::CompizMinimizedWindowHandler<Screen, Window>::handleEvent (XEvent *event)
 
287
{
 
288
  if (screen->XShape () && event->type ==
 
289
      screen->shapeEvent () + ShapeNotify)
 
290
  {
 
291
    CompWindow *w = screen->findWindow (((XShapeEvent *) event)->window);
 
292
 
 
293
    if (w)
 
294
    {
 
295
      typedef compiz::CompizMinimizedWindowHandler<Screen, Window> plugin_handler;
 
296
      Window *pw = Window::get (w);
 
297
      plugin_handler::Ptr compizMinimizeHandler =
 
298
        boost::dynamic_pointer_cast <plugin_handler> (pw->mMinimizeHandler);
 
299
      /* Restore and re-save input shape and remove */
 
300
      if (compizMinimizeHandler)
 
301
      {
 
302
        compizMinimizeHandler->setVisibility (true);
 
303
        compizMinimizeHandler->setVisibility (false);
 
304
      }
 
305
    }
 
306
  }
 
307
}
 
308
 
 
309
template <typename Screen, typename Window>
 
310
void
 
311
compiz::CompizMinimizedWindowHandler<Screen, Window>::setFunctions (bool keepMinimized)
 
312
{
 
313
  for (CompWindow *w : screen->windows ())
 
314
  {
 
315
    bool m = w->minimized ();
 
316
 
 
317
    if (m)
 
318
      w->unminimize ();
 
319
    w->minimizeSetEnabled (Window::get (w), keepMinimized);
 
320
    w->unminimizeSetEnabled (Window::get (w), keepMinimized);
 
321
    w->minimizedSetEnabled (Window::get (w), keepMinimized);
 
322
    if (m)
 
323
      Window::get (w)->window->minimize ();
 
324
  }
 
325
}
 
326
 
 
327
#endif