XWalk WebView patchset, README and LICENSE files.
[platform/framework/web/xwalk_webview.git] / patchset / 0024-Fixed-content-shell-content-rendering-crash-on-exit..patch
1 From 86cdb77f07cd35265d131c5648b02c14915b4674 Mon Sep 17 00:00:00 2001
2 From: Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
3 Date: Tue, 13 Aug 2013 15:18:04 +0300
4 Subject: [PATCH 24/33] Fixed content shell: content rendering & crash on exit.
5  Deep refactoring of PreserveWindow (as a part of crash fixing).
6
7 ---
8  content/shell/shell_efl.cc                         |   8 +-
9  .../shell/shell_web_contents_view_delegate_efl.cc  |   6 +-
10  efl_webview/lib/webview.h                          |   2 +-
11  ui/gfx/preserve_window_efl.cc                      | 413 ++++++++-------------
12  ui/gfx/preserve_window_efl.h                       |  14 +-
13  5 files changed, 165 insertions(+), 278 deletions(-)
14
15 diff --git a/content/shell/shell_efl.cc b/content/shell/shell_efl.cc
16 index f847113..36559ca 100644
17 --- a/content/shell/shell_efl.cc
18 +++ b/content/shell/shell_efl.cc
19 @@ -65,7 +65,7 @@ void Shell::PlatformSetContents() {
20    if (headless_)
21      return;
22  
23 -  container_view_ = elm_box_add(window_);
24 +  container_view_ = evas_object_box_add(evas_object_evas_get(window_));
25    evas_object_size_hint_weight_set(container_view_,
26                                     EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
27  
28 @@ -81,8 +81,6 @@ void Shell::PlatformSetContents() {
29  void Shell::SizeTo(int width, int height) {
30    content_width_ = width;
31    content_height_ = height;
32 -  if (web_contents_) {
33 -  }
34  }
35  
36  void Shell::PlatformResizeSubViews() {
37 @@ -111,9 +109,7 @@ void Shell::OnMainWindowDel(void* data, Evas* evas, Evas_Object* object,
38  }
39  
40  bool Shell::TakeFocus(WebContents* source, bool reverse) {
41 -  DCHECK(source == web_contents_.get());
42 -  elm_object_focus_next(container_view_,
43 -                        reverse ? ELM_FOCUS_PREVIOUS : ELM_FOCUS_NEXT);
44 +  evas_object_focus_set(container_view_, EINA_FALSE);
45    return true;
46  }
47  
48 diff --git a/content/shell/shell_web_contents_view_delegate_efl.cc b/content/shell/shell_web_contents_view_delegate_efl.cc
49 index 8221da0..9b95417 100644
50 --- a/content/shell/shell_web_contents_view_delegate_efl.cc
51 +++ b/content/shell/shell_web_contents_view_delegate_efl.cc
52 @@ -4,7 +4,6 @@
53  
54  #include "content/shell/shell_web_contents_view_delegate.h"
55  
56 -#include <Elementary.h>
57  #include "base/command_line.h"
58  #include "content/public/browser/render_process_host.h"
59  #include "content/public/browser/render_view_host.h"
60 @@ -51,8 +50,9 @@ WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() {
61  }
62  
63  void ShellWebContentsViewDelegate::Focus() {
64 -  if (native_view_)
65 -    elm_object_focus_set(native_view_, EINA_TRUE);
66 +  if (!native_view_)
67 +    return;
68 +  evas_object_focus_set(native_view_, EINA_TRUE);
69  }
70  
71  void ShellWebContentsViewDelegate::UpdateTitle(const string16& title) {
72 diff --git a/efl_webview/lib/webview.h b/efl_webview/lib/webview.h
73 index 985ef160..710d731 100644
74 --- a/efl_webview/lib/webview.h
75 +++ b/efl_webview/lib/webview.h
76 @@ -31,7 +31,7 @@ class WebView {
77  
78    ~WebView();
79  
80 -  EAPI Evas_Object* EvasObject();
81 +  Evas_Object* EvasObject();
82  
83    bool CanGoBack() const;
84    bool CanGoForward() const;
85 diff --git a/ui/gfx/preserve_window_efl.cc b/ui/gfx/preserve_window_efl.cc
86 index 827836b..6c901a7 100644
87 --- a/ui/gfx/preserve_window_efl.cc
88 +++ b/ui/gfx/preserve_window_efl.cc
89 @@ -17,68 +17,37 @@
90  namespace gfx {
91  
92  namespace {
93 -#define evas_smart_preserve_window_type "Evas_Smart_Preserve_Window"
94 -
95 -const char PRESERVE_WINDOW_MOVE[] = "preserve,moved";
96 -const char PRESERVE_WINDOW_RESIZE[] = "preserve,resized";
97 -const char PRESERVE_WINDOW_REPAINT[] = "preserve,repainted";
98 -const Evas_Smart_Cb_Description g_smart_callbacks[] = {
99 -    {PRESERVE_WINDOW_MOVE, "(ii)"},
100 -    {PRESERVE_WINDOW_RESIZE, "(ii)"},
101 -    {PRESERVE_WINDOW_REPAINT, "(iiii)"},
102 -    {NULL, NULL}};
103 -
104 -enum PreserveWindowSmartEventType {
105 -  PreserveWindowMoveType,
106 -  PreserveWindowResizeType,
107 -  PreserveWindowRepaintType,
108 -};
109 -
110 -const char* PreserveWindowSmartEvent(PreserveWindowSmartEventType type) {
111 -  switch (type) {
112 -    case PreserveWindowMoveType:
113 -      return PRESERVE_WINDOW_MOVE;
114 -      break;
115 -    case PreserveWindowResizeType:
116 -      return PRESERVE_WINDOW_RESIZE;
117 -      break;
118 -    case PreserveWindowRepaintType:
119 -      return PRESERVE_WINDOW_REPAINT;
120 -      break;
121 -  }
122 -  NOTREACHED();
123 -  return "";
124 -}
125 +const char evas_smart_preserve_window_type[] = "Evas_Smart_Preserve_Window";
126  
127  struct PreserveWindowData {
128 -   Evas_Object_Smart_Clipped_Data base;
129 -   Ecore_X_Window window_;
130 -   Evas_Object* background_;
131 +  Evas_Object_Smart_Clipped_Data base;
132 +  Ecore_X_Window window;
133 +  Evas_Object* background;
134 +  gfx::PreserveWindow* self;
135  };
136  
137  bool IsPreserveWindowEvasObject(const Evas_Object* evas_object) {
138 -    DCHECK(evas_object);
139 +  DCHECK(evas_object);
140  
141 -    const char* evas_object_type = evas_object_type_get(evas_object);
142 -    if (!evas_object_smart_type_check(evas_object,
143 +  const char* evas_object_type = evas_object_type_get(evas_object);
144 +  if (!evas_object_smart_type_check(evas_object,
145                                        evas_smart_preserve_window_type)) {
146 -      LOG(ERROR) << evas_object << " is not of an "<< evas_object_type << "!";
147 -        return false;
148 -    }
149 -
150 -    const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
151 -    if (!evas_smart) {
152 -        LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart object!";
153 -        return false;
154 -    }
155 +    LOG(ERROR) << evas_object << " is not of an "<< evas_object_type << "!";
156 +      return false;
157 +  }
158  
159 -    const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
160 -    if (!smart_class) {
161 -      LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart class object!";
162 -        return false;
163 -    }
164 +  const Evas_Smart* evas_smart = evas_object_smart_smart_get(evas_object);
165 +  if (!evas_smart) {
166 +      LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart object!";
167 +      return false;
168 +  }
169  
170 -    return true;
171 +  const Evas_Smart_Class* smart_class = evas_smart_class_get(evas_smart);
172 +  if (!smart_class) {
173 +    LOG(ERROR) << evas_object << "(" << evas_object_type << ") is not a smart class object!";
174 +      return false;
175 +  }
176 +  return true;
177  }
178  
179  inline PreserveWindowData* ToSmartData(Evas_Object* evas_object) {
180 @@ -93,132 +62,11 @@ EVAS_SMART_SUBCLASS_NEW(evas_smart_preserve_window_type,
181                          Evas_Smart_Class,
182                          Evas_Smart_Class,
183                          evas_object_smart_clipped_class_get,
184 -                        g_smart_callbacks);
185 -
186 -/* create and setup a new preserve window smart object's internals */
187 -void evas_smart_preserve_window_smart_add(Evas_Object* o) {
188 -  // Don't use EVAS_SMART_DATA_ALLOC(o, PreserveWindowData)
189 -  // because [-fpermissive] does not allow invalid conversion from 'void*' to 'PreserveWindowData*'.
190 -  PreserveWindowData* smart_data;
191 -  smart_data = static_cast<PreserveWindowData*>(evas_object_smart_data_get(o));
192 -  if (!smart_data) {
193 -    smart_data = static_cast<PreserveWindowData*>(calloc(1, sizeof(PreserveWindowData)));
194 -    if (!smart_data) {
195 -      return;
196 -    }
197 -    evas_object_smart_data_set(o, smart_data);
198 -  }
199 -
200 -  Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(o));
201 -  Ecore_X_Window x_window_id = 0;
202 -  const char* engine_name = ecore_evas_engine_name_get(ee);
203 -  if (!strncmp(engine_name, "software_x11", 12)) {
204 -    x_window_id = ecore_evas_software_x11_window_get(ee);
205 -  } else if (!strncmp(engine_name, "opengl_x11", 10)) {
206 -    x_window_id = ecore_evas_gl_x11_window_get(ee);
207 -  } else {
208 -    LOG(FATAL) << "Unsupported Evas engine " << engine_name << "! Please add it to evas_smart_preserve_window_smart_add().";
209 -  }
210 -
211 -  smart_data->window_ = ecore_x_window_new(x_window_id, 0, 0, 1, 1);
212 -
213 -  // Do not listen to any events in this new window, otherwise they will not be
214 -  // propagated to the parent X window (the one which is actually interested in
215 -  // them).
216 -  XSetWindowAttributes attributes;
217 -  attributes.event_mask = NoEventMask;
218 -  XChangeWindowAttributes(static_cast<Display*>(ecore_x_display_get()),
219 -                          smart_data->window_, CWEventMask, &attributes);
220 -
221 -  smart_data->background_ = evas_object_rectangle_add(evas_object_evas_get(o));
222 -  evas_object_color_set(smart_data->background_, 0, 0, 0, 0);
223 -  evas_object_size_hint_weight_set(smart_data->background_, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
224 -  evas_object_focus_set(smart_data->background_, EINA_TRUE);
225 -  evas_smart_preserve_window_parent_sc->add(o);
226 -}
227 -
228 -void evas_smart_preserve_window_smart_del(Evas_Object* o) {
229 -  PreserveWindowData* smart_data = ToSmartData(o);
230 -  evas_object_del(smart_data->background_);
231 -  ecore_x_window_free(smart_data->window_);
232 -  evas_smart_preserve_window_parent_sc->del(o);
233 -}
234 -
235 -void evas_smart_preserve_window_smart_show(Evas_Object* o) {
236 -  PreserveWindowData* smart_data = ToSmartData(o);
237 -  ecore_x_window_show(smart_data->window_);
238 -  evas_object_show(smart_data->background_);
239 -  evas_smart_preserve_window_parent_sc->show(o);
240 -}
241 -
242 -void evas_smart_preserve_window_smart_hide(Evas_Object* o) {
243 -  PreserveWindowData* smart_data = ToSmartData(o);
244 -  ecore_x_window_hide(smart_data->window_);
245 -  evas_object_hide(smart_data->background_);
246 -  evas_smart_preserve_window_parent_sc->hide(o);
247 -}
248 -
249 -void evas_smart_preserve_window_smart_move(Evas_Object* o,
250 -                                           Evas_Coord x,
251 -                                           Evas_Coord y) {
252 -  Evas_Coord ox, oy;
253 -  evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
254 -  if ((ox == x) && (oy == y))
255 -    return;
256 -
257 -  PreserveWindowData* smart_data = ToSmartData(o);
258 -  ecore_x_window_move(smart_data->window_, x, y);
259 -  evas_object_move(smart_data->background_, x, y);
260 -
261 -  int position[2] = {x, y};
262 -  evas_object_smart_callback_call(
263 -      o, PRESERVE_WINDOW_MOVE, static_cast<void*>(position));
264 -
265 -  /* this will trigger recalculation */
266 -  evas_object_smart_changed(o);
267 -}
268 -
269 -void evas_smart_preserve_window_smart_resize(Evas_Object* o,
270 -                                             Evas_Coord w,
271 -                                             Evas_Coord h) {
272 -  Evas_Coord ow, oh;
273 -  evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
274 -  if ((ow == w) && (oh == h))
275 -    return;
276 -
277 -  PreserveWindowData* smart_data = ToSmartData(o);
278 -  ecore_x_window_resize(smart_data->window_, w, h);
279 -  evas_object_resize(smart_data->background_, w, h);
280 -
281 -  int size[2] = {w, h};
282 -  evas_object_smart_callback_call(
283 -      o, PRESERVE_WINDOW_RESIZE, static_cast<void*>(size));
284 -
285 -  /* this will trigger recalculation */
286 -  evas_object_smart_changed(o);
287 -}
288 -
289 -/* act on child objects' properties, before rendering */
290 -void evas_smart_preserve_window_smart_calculate(Evas_Object* o) {
291 -  int dirty_rect[4] = { 0, };
292 -  // FIXME: how to know dirty rect actually.
293 -  evas_object_geometry_get(o, &dirty_rect[0], &dirty_rect[1], &dirty_rect[2], &dirty_rect[3]);
294 -  evas_object_smart_callback_call(
295 -      o, PRESERVE_WINDOW_REPAINT, static_cast<void*>(dirty_rect));
296 -}
297 +                        0);
298  
299  /* setting our smart interface */
300 -void evas_smart_preserve_window_smart_set_user(Evas_Smart_Class* sc) {
301 -  /* specializing these two */
302 -  sc->add = evas_smart_preserve_window_smart_add;
303 -  sc->del = evas_smart_preserve_window_smart_del;
304 -  sc->show = evas_smart_preserve_window_smart_show;
305 -  sc->hide = evas_smart_preserve_window_smart_hide;
306 -
307 -  /* clipped smart object has no hook on move, resize and calculation */
308 -  sc->move = evas_smart_preserve_window_smart_move;
309 -  sc->resize = evas_smart_preserve_window_smart_resize;
310 -  sc->calculate = evas_smart_preserve_window_smart_calculate;
311 +inline void evas_smart_preserve_window_smart_set_user(Evas_Smart_Class* sc) {
312 +  PreserveWindow::InitSmartClassInterface(sc);
313  }
314  
315  // SmartObjectEventHandler implementation.
316 @@ -228,10 +76,6 @@ template <Evas_Callback_Type EventType> class SmartObjectEventHandler {
317      evas_object_event_callback_add(evas_object, EventType, HandleEvent, delegate);
318    }
319  
320 -  static void Unsubscribe(Evas_Object* evas_object) {
321 -    evas_object_event_callback_del(evas_object, EventType, HandleEvent);
322 -  }
323 -
324    static void HandleEvent(void* data, Evas*, Evas_Object*, void* event_info);
325  };
326  
327 @@ -305,71 +149,126 @@ void SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::HandleEvent(
328    delegate->PreserveWindowHide();
329  }
330  
331 -// SmartObjectSmartHandler implementation.
332 -template <PreserveWindowSmartEventType EventType> class SmartObjectSmartHandler {
333 - public:
334 -  static void Subscribe(Evas_Object* evas_object, PreserveWindowDelegate* delegate) {
335 -    evas_object_smart_callback_add(evas_object,
336 -                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
337 -                                   HandleEventMove, delegate);
338 -    evas_object_smart_callback_add(evas_object,
339 -                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
340 -                                   HandleEventResize, delegate);
341 -    evas_object_smart_callback_add(evas_object,
342 -                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
343 -                                   HandleEventRepaint, delegate);
344 +}  // namespace
345 +
346 +// static
347 +PreserveWindow* PreserveWindow::Create(PreserveWindowDelegate* delegate,
348 +                                       Evas* evas) {
349 +  return new PreserveWindow(delegate, evas);
350 +}
351 +
352 +void PreserveWindow::InitSmartClassInterface(Evas_Smart_Class* sc) {
353 +  sc->add = HandleEvasObjectAdd;
354 +  sc->del = HandleEvasObjectDelete;
355 +  sc->show = HandleEvasObjectShow;
356 +  sc->hide = HandleEvasObjectHide;
357 +  sc->move = HandleEvasObjectMove;
358 +  sc->resize = HandleEvasObjectResize;
359 +  sc->calculate = HandleEvasObjectCalculate;  // Empty function, but we have to provide something - efl is crashing otherwise.
360 +}
361 +
362 +void PreserveWindow::HandleEvasObjectAdd(Evas_Object* o) {
363 +  // Don't use EVAS_SMART_DATA_ALLOC(o, PreserveWindowData)
364 +  // because [-fpermissive] does not allow invalid conversion from 'void*' to 'PreserveWindowData*'.
365 +  PreserveWindowData* smart_data;
366 +  smart_data = static_cast<PreserveWindowData*>(evas_object_smart_data_get(o));
367 +  if (!smart_data) {
368 +    smart_data = static_cast<PreserveWindowData*>(calloc(1, sizeof(PreserveWindowData)));
369 +    if (!smart_data) {
370 +      return;
371 +    }
372 +    evas_object_smart_data_set(o, smart_data);
373    }
374  
375 -  static void Unsubscribe(Evas_Object* evas_object) {
376 -    evas_object_smart_callback_del(evas_object,
377 -                                   PreserveWindowSmartEvent(PreserveWindowMoveType),
378 -                                   HandleEventMove);
379 -    evas_object_smart_callback_del(evas_object,
380 -                                   PreserveWindowSmartEvent(PreserveWindowResizeType),
381 -                                   HandleEventResize);
382 -    evas_object_smart_callback_del(evas_object,
383 -                                   PreserveWindowSmartEvent(PreserveWindowRepaintType),
384 -                                   HandleEventRepaint);
385 +  Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(o));
386 +  Ecore_X_Window x_window_id = 0;
387 +  const char* engine_name = ecore_evas_engine_name_get(ee);
388 +  if (!strncmp(engine_name, "software_x11", 12)) {
389 +    x_window_id = ecore_evas_software_x11_window_get(ee);
390 +  } else if (!strncmp(engine_name, "opengl_x11", 10)) {
391 +    x_window_id = ecore_evas_gl_x11_window_get(ee);
392 +  } else {
393 +    LOG(FATAL) << "Unsupported Evas engine " << engine_name << "! Please add it to evas_smart_preserve_window_smart_add().";
394    }
395  
396 -  static void HandleEventMove(void* data, Evas_Object*, void* event_info);
397 -  static void HandleEventResize(void* data, Evas_Object*, void* event_info);
398 -  static void HandleEventRepaint(void* data, Evas_Object*, void* event_info);
399 -};
400 +  smart_data->window = ecore_x_window_new(x_window_id, 0, 0, 1, 1);
401  
402 -template <PreserveWindowSmartEventType EventType>
403 -void SmartObjectSmartHandler<EventType>::HandleEventMove(
404 -    void* data, Evas_Object*, void* event_info) {
405 -  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
406 -  int* position = static_cast<int*>(event_info);
407 -  delegate->PreserveWindowMove(gfx::Point(position[0], position[1]));
408 +  // Do not listen to any events in this new window, otherwise they will not be
409 +  // propagated to the parent X window (the one which is actually interested in
410 +  // them).
411 +  XSetWindowAttributes attributes;
412 +  attributes.event_mask = NoEventMask;
413 +  XChangeWindowAttributes(static_cast<Display*>(ecore_x_display_get()),
414 +                          smart_data->window, CWEventMask, &attributes);
415 +
416 +  smart_data->background = evas_object_rectangle_add(evas_object_evas_get(o));
417 +  evas_object_color_set(smart_data->background, 0, 0, 0, 0);
418 +  evas_object_size_hint_weight_set(smart_data->background, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
419 +  evas_object_focus_set(smart_data->background, EINA_TRUE);
420 +  evas_smart_preserve_window_parent_sc->add(o);
421  }
422  
423 -template <PreserveWindowSmartEventType EventType>
424 -void SmartObjectSmartHandler<EventType>::HandleEventResize(
425 -    void* data, Evas_Object*, void* event_info) {
426 -  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
427 -  int* size = static_cast<int*>(event_info);
428 -  delegate->PreserveWindowResize(gfx::Size(size[0], size[1]));
429 +void PreserveWindow::HandleEvasObjectDelete(Evas_Object* o) {
430 +  PreserveWindowData* smart_data = ToSmartData(o);
431 +  evas_object_del(smart_data->background);
432 +  ecore_x_window_free(smart_data->window);
433 +
434 +  smart_data->self->smart_object_ = 0;  // We let PreserveWindow know that its smart_object_ does not exist any more.
435 +
436 +  evas_smart_preserve_window_parent_sc->del(o);
437  }
438  
439 -template <PreserveWindowSmartEventType EventType>
440 -void SmartObjectSmartHandler<EventType>::HandleEventRepaint(
441 -    void* data, Evas_Object*, void* event_info) {
442 -  PreserveWindowDelegate* delegate = static_cast<PreserveWindowDelegate*>(data);
443 -  int* dirty_rect = static_cast<int*>(event_info);
444 -  delegate->PreserveWindowRepaint(gfx::Rect(dirty_rect[0],
445 -                                            dirty_rect[1],
446 -                                            dirty_rect[2],
447 -                                            dirty_rect[3]));
448 +void PreserveWindow::HandleEvasObjectShow(Evas_Object* o) {
449 +  PreserveWindowData* smart_data = ToSmartData(o);
450 +  ecore_x_window_show(smart_data->window);
451 +  evas_object_show(smart_data->background);
452 +  evas_smart_preserve_window_parent_sc->show(o);
453  }
454  
455 -}  // namespace
456 +void PreserveWindow::HandleEvasObjectHide(Evas_Object* o) {
457 +  PreserveWindowData* smart_data = ToSmartData(o);
458 +  ecore_x_window_hide(smart_data->window);
459 +  evas_object_hide(smart_data->background);
460 +  evas_smart_preserve_window_parent_sc->hide(o);
461 +}
462  
463 -// static
464 -PreserveWindow* PreserveWindow::Create(PreserveWindowDelegate* delegate,
465 -                                       Evas* evas) {
466 -  return new PreserveWindow(delegate, evas);
467 +void PreserveWindow::HandleEvasObjectMove(Evas_Object* o,
468 +                                          Evas_Coord x,
469 +                                          Evas_Coord y) {
470 +  Evas_Coord ox, oy;
471 +  evas_object_geometry_get(o, &ox, &oy, NULL, NULL);
472 +  if ((ox == x) && (oy == y))
473 +    return;
474 +
475 +  PreserveWindowData* smart_data = ToSmartData(o);
476 +  ecore_x_window_move(smart_data->window, x, y);
477 +  evas_object_move(smart_data->background, x, y);
478 +
479 +  smart_data->self->delegate_->PreserveWindowMove(gfx::Point(x, y));
480 +
481 +  // This will trigger recalculation.
482 +  evas_object_smart_changed(o);
483 +}
484 +
485 +void PreserveWindow::HandleEvasObjectResize(Evas_Object* o,
486 +                                            Evas_Coord w,
487 +                                            Evas_Coord h) {
488 +  Evas_Coord ow, oh;
489 +  evas_object_geometry_get(o, NULL, NULL, &ow, &oh);
490 +  if ((ow == w) && (oh == h))
491 +    return;
492 +
493 +  PreserveWindowData* smart_data = ToSmartData(o);
494 +  ecore_x_window_resize(smart_data->window, w, h);
495 +  evas_object_resize(smart_data->background, w, h);
496 +
497 +  smart_data->self->delegate_->PreserveWindowResize(gfx::Size(w, h));
498 +
499 +  /* this will trigger recalculation */
500 +  evas_object_smart_changed(o);
501 +}
502 +
503 +void PreserveWindow::HandleEvasObjectCalculate(Evas_Object* o) {
504  }
505  
506  PreserveWindow::PreserveWindow(PreserveWindowDelegate* delegate, Evas* evas)
507 @@ -377,49 +276,31 @@ PreserveWindow::PreserveWindow(PreserveWindowDelegate* delegate, Evas* evas)
508    smart_object_ = evas_object_smart_add(evas, evas_smart_preserve_window_smart_class_new());
509    evas_object_show(smart_object_);
510  
511 -  SmartObjectSmartHandler<PreserveWindowMoveType>::Subscribe(smart_object_, delegate_);
512 -  SmartObjectSmartHandler<PreserveWindowResizeType>::Subscribe(smart_object_, delegate_);
513 -  SmartObjectSmartHandler<PreserveWindowRepaintType>::Subscribe(smart_object_, delegate_);
514 -
515    PreserveWindowData* smart_data = ToSmartData(smart_object_);
516 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Subscribe(smart_data->background_, delegate_);
517 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Subscribe(smart_data->background_, delegate_);
518 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Subscribe(smart_data->background_, delegate_);
519 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Subscribe(smart_data->background_, delegate_);
520 -  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Subscribe(smart_data->background_, delegate_);
521 -  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Subscribe(smart_data->background_, delegate_);
522 -  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Subscribe(smart_data->background_, delegate_);
523 -  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Subscribe(smart_data->background_, delegate_);
524 -  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Subscribe(smart_data->background_, delegate_);
525 -  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Subscribe(smart_data->background_, delegate_);
526 +  smart_data->self = this;
527 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Subscribe(smart_data->background, delegate_);
528 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Subscribe(smart_data->background, delegate_);
529 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Subscribe(smart_data->background, delegate_);
530 +  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Subscribe(smart_data->background, delegate_);
531 +  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Subscribe(smart_data->background, delegate_);
532 +  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Subscribe(smart_data->background, delegate_);
533 +  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Subscribe(smart_data->background, delegate_);
534 +  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Subscribe(smart_data->background, delegate_);
535 +  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Subscribe(smart_data->background, delegate_);
536 +  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Subscribe(smart_data->background, delegate_);
537  
538    // FIXME: After creation, request redraw.
539    evas_object_smart_changed(smart_object_);
540  }
541  
542  PreserveWindow::~PreserveWindow() {
543 -  SmartObjectSmartHandler<PreserveWindowMoveType>::Unsubscribe(smart_object_);
544 -  SmartObjectSmartHandler<PreserveWindowResizeType>::Unsubscribe(smart_object_);
545 -  SmartObjectSmartHandler<PreserveWindowRepaintType>::Unsubscribe(smart_object_);
546 -
547 -  PreserveWindowData* smart_data = ToSmartData(smart_object_);
548 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_DOWN>::Unsubscribe(smart_data->background_);
549 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_UP>::Unsubscribe(smart_data->background_);
550 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_MOVE>::Unsubscribe(smart_data->background_);
551 -  SmartObjectEventHandler<EVAS_CALLBACK_MOUSE_WHEEL>::Unsubscribe(smart_data->background_);
552 -  SmartObjectEventHandler<EVAS_CALLBACK_KEY_DOWN>::Unsubscribe(smart_data->background_);
553 -  SmartObjectEventHandler<EVAS_CALLBACK_KEY_UP>::Unsubscribe(smart_data->background_);
554 -  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_IN>::Unsubscribe(smart_data->background_);
555 -  SmartObjectEventHandler<EVAS_CALLBACK_FOCUS_OUT>::Unsubscribe(smart_data->background_);
556 -  SmartObjectEventHandler<EVAS_CALLBACK_SHOW>::Unsubscribe(smart_data->background_);
557 -  SmartObjectEventHandler<EVAS_CALLBACK_HIDE>::Unsubscribe(smart_data->background_);
558 -
559 -  evas_object_del(smart_object_);
560 +  if (smart_object_) // smart_object_ can be deleted earlier by efl framework - via efl event loop (happens with content shell).
561 +    evas_object_del(smart_object_);  
562  }
563  
564  gfx::PluginWindowHandle PreserveWindow::EmbeddedXWindow() {
565    PreserveWindowData* smart_data = ToSmartData(smart_object_);
566 -  return smart_data->window_;
567 +  return smart_data->window;
568  }
569  
570  }  // namespace gfx
571 diff --git a/ui/gfx/preserve_window_efl.h b/ui/gfx/preserve_window_efl.h
572 index 1097072..6cb48ba 100644
573 --- a/ui/gfx/preserve_window_efl.h
574 +++ b/ui/gfx/preserve_window_efl.h
575 @@ -17,15 +17,25 @@ namespace gfx {
576  
577  class UI_EXPORT PreserveWindow {
578   public:
579 -  static PreserveWindow* Create(PreserveWindowDelegate*, Evas*);
580 +  static PreserveWindow* Create(PreserveWindowDelegate* delegate, Evas* canvas);
581  
582    ~PreserveWindow();
583  
584    Evas_Object* SmartObject() const { return smart_object_; }
585    PluginWindowHandle EmbeddedXWindow();
586  
587 +  static void InitSmartClassInterface(Evas_Smart_Class* smart_class);
588 +
589   private:
590 -  PreserveWindow(PreserveWindowDelegate*, Evas*);
591 +  PreserveWindow(PreserveWindowDelegate* delegate, Evas* canvas);
592 +
593 +  static void HandleEvasObjectAdd(Evas_Object* evas_object);
594 +  static void HandleEvasObjectDelete(Evas_Object* evas_object);
595 +  static void HandleEvasObjectShow(Evas_Object* evas_object);
596 +  static void HandleEvasObjectHide(Evas_Object* evas_object);
597 +  static void HandleEvasObjectMove(Evas_Object*, Evas_Coord x, Evas_Coord y);
598 +  static void HandleEvasObjectResize(Evas_Object* evas_object, Evas_Coord width, Evas_Coord height);
599 +  static void HandleEvasObjectCalculate(Evas_Object* evas_object);
600  
601    PreserveWindowDelegate* delegate_;
602    Evas_Object* smart_object_;
603 -- 
604 1.8.1.2
605