[elm_conformant.c] default contetnt part is removed.
[framework/uifw/elementary.git] / src / lib / elm_conform.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 #ifndef MIN
5 # define MIN(a,b) ((a) < (b)) ? (a) : (b)
6 #endif
7
8 #ifndef MAX
9 # define MAX(a,b) ((a) < (b)) ? (b) : (a)
10 #endif
11
12 typedef struct _Widget_Data Widget_Data;
13 struct _Widget_Data
14 {
15    Evas_Object *base;
16    Evas_Object *shelf, *panel, *virtualkeypad, *sliding_win;
17    Evas_Object *content;
18    Evas_Object *scroller;
19    int is_sliding_win_visible;
20 #ifdef HAVE_ELEMENTARY_X
21    Ecore_Event_Handler *prop_hdl;
22    Ecore_X_Virtual_Keyboard_State vkb_state;
23 #endif
24    struct
25    {
26       Ecore_Animator *animator; // animaton timer
27       double start; // time started
28       Evas_Coord auto_x, auto_y; // desired delta
29       Evas_Coord x, y; // current delta
30    } delta;
31    Ecore_Job *show_region_job;
32 };
33
34 /* Enum to identify conformant swallow parts */
35 typedef enum _Conformant_Part_Type Conformant_Part_Type;
36 enum _Conformant_Part_Type
37 {
38    ELM_CONFORM_INDICATOR_PART      = 1,
39    ELM_CONFORM_SOFTKEY_PART        = 2,
40    ELM_CONFORM_VIRTUAL_KEYPAD_PART = 4,
41    ELM_CONFORM_SLIDING_WIN_PART    = 8
42 };
43
44 #define SUB_TYPE_COUNT 2
45 static char *sub_type[SUB_TYPE_COUNT] = { "scroller", "genlist" };
46
47 /* local function prototypes */
48 static const char *widtype = NULL;
49 static void _del_pre_hook(Evas_Object *obj);
50 static void _del_hook(Evas_Object *obj);
51 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
52 static void _theme_hook(Evas_Object *obj);
53 static void _content_set_hook(Evas_Object *obj,
54                               const char *part,
55                               Evas_Object *content);
56 static Evas_Object *_content_get_hook(const Evas_Object *obj,
57                                       const char *part);
58 static Evas_Object *_content_unset_hook(Evas_Object *obj, const char *part);
59 static void _swallow_conformant_parts(Evas_Object *obj);
60 static void _conformant_part_size_set(Evas_Object *obj,
61                                       Evas_Object *sobj,
62                                       Evas_Coord sx,
63                                       Evas_Coord sy,
64                                       Evas_Coord sw,
65                                       Evas_Coord sh);
66 static void _conformant_part_sizing_eval(Evas_Object *obj,
67                                          Conformant_Part_Type part_type);
68 static void _conformant_move_resize_event_cb(void *data,
69                                              Evas *e,
70                                              Evas_Object *obj,
71                                              void *event_info);
72 static void _sizing_eval(Evas_Object *obj);
73 static void _show_region_job(void *data);
74 static Eina_Bool _prop_change(void *data, int type, void *event);
75 static void _changed_size_hints(void *data, Evas *e,
76                                 Evas_Object *obj,
77                                 void *event_info);
78
79 /* local functions */
80 static void
81 _del_pre_hook(Evas_Object *obj)
82 {
83    Widget_Data *wd = elm_widget_data_get(obj);
84    if (!wd) return;
85 #ifdef HAVE_ELEMENTARY_X
86    if (wd->prop_hdl) ecore_event_handler_del(wd->prop_hdl);
87 #endif
88 }
89
90 static void
91 _del_hook(Evas_Object *obj)
92 {
93    Widget_Data *wd = elm_widget_data_get(obj);
94
95    if (!wd) return;
96    if (wd->show_region_job) ecore_job_del(wd->show_region_job);
97    free(wd);
98 }
99
100 static void
101 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
102 {
103    Widget_Data *wd = elm_widget_data_get(obj);
104
105    if (!wd) return;
106    edje_object_mirrored_set(wd->base, rtl);
107 }
108
109 static void
110 _theme_hook(Evas_Object *obj)
111 {
112    Widget_Data *wd = elm_widget_data_get(obj);
113
114    if (!wd) return;
115    _elm_widget_mirrored_reload(obj);
116    _mirrored_set(obj, elm_widget_mirrored_get(obj));
117    _elm_theme_object_set(obj, wd->base, "conformant", "base",
118                          elm_widget_style_get(obj));
119    _swallow_conformant_parts(obj);
120
121    if (wd->content)
122      edje_object_part_swallow(wd->base, "elm.swallow.content", wd->content);
123    edje_object_scale_set(wd->base, elm_widget_scale_get(obj)
124                          * _elm_config->scale);
125    _sizing_eval(obj);
126 }
127
128 static void
129 _content_set_hook(Evas_Object *obj, const char *part, Evas_Object *content)
130 {
131    ELM_CHECK_WIDTYPE(obj, widtype);
132    Widget_Data *wd;
133
134    if (part && strcmp(part, "default")) return;
135    wd = elm_widget_data_get(obj);
136    if (!wd) return;
137    if (wd->content == content) return;
138    if (wd->content) evas_object_del(wd->content);
139    wd->content = content;
140    if (content)
141      {
142         elm_widget_sub_object_add(obj, content);
143         evas_object_event_callback_add(content,
144                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
145                                        _changed_size_hints, obj);
146         edje_object_part_swallow(wd->base, "elm.swallow.content", content);
147      }
148    _sizing_eval(obj);
149 }
150
151 static Evas_Object *
152 _content_get_hook(const Evas_Object *obj, const char *part)
153 {
154    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
155    Widget_Data *wd;
156
157    if (part && strcmp(part, "default")) return NULL;
158    wd = elm_widget_data_get(obj);
159    if (!wd) return NULL;
160    return wd->content;
161 }
162
163 static Evas_Object *
164 _content_unset_hook(Evas_Object *obj, const char *part)
165 {
166    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
167    Widget_Data *wd;
168    Evas_Object *content;
169    if (part && strcmp(part, "default")) return NULL;
170    wd = elm_widget_data_get(obj);
171    if ((!wd) || (!wd->content)) return NULL;
172    content = wd->content;
173    elm_widget_sub_object_del(obj, wd->content);
174    evas_object_event_callback_del_full(wd->content,
175                                        EVAS_CALLBACK_CHANGED_SIZE_HINTS,
176                                        _changed_size_hints, obj);
177    edje_object_part_unswallow(wd->base, wd->content);
178    wd->content = NULL;
179    return content;
180 }
181
182 static void
183 _sizing_eval(Evas_Object *obj)
184 {
185    Widget_Data *wd = elm_widget_data_get(obj);
186    Evas_Coord mw = -1, mh = -1;
187
188    if (!wd) return;
189    edje_object_size_min_calc(wd->base, &mw, &mh);
190    evas_object_size_hint_min_set(obj, mw, mh);
191    evas_object_size_hint_max_set(obj, -1, -1);
192 }
193
194 /* Example of env vars:
195  * ILLUME_KBD="0, 0, 800, 301"
196  * ILLUME_IND=0,0,800,32
197  * ILLUME_STK="0,568,800,32
198  */
199 static Eina_Bool
200 _conformant_part_geometry_env_get(const char *part, int *sx, int *sy, int *sw, int *sh)
201 {
202    const char delimiters[] = " ,;";
203    char *env_val, *token;
204    char buf[PATH_MAX];
205    int tsx, tsy, tsw;
206
207    if (!(env_val = getenv(part))) return EINA_FALSE;
208
209    /* strtok would modify env var if not copied to a buffer */
210    strncpy(buf, env_val, sizeof(buf));
211
212    token = strtok(buf, delimiters);
213    if (!token) return EINA_FALSE;
214    tsx = atoi(token);
215
216    token = strtok(NULL, delimiters);
217    if (!token) return EINA_FALSE;
218    tsy = atoi(token);
219
220    token = strtok(NULL, delimiters);
221    if (!token) return EINA_FALSE;
222    tsw = atoi(token);
223
224    token = strtok(NULL, delimiters);
225    if (!token) return EINA_FALSE;
226    *sh = atoi(token);
227
228    *sx = tsx;
229    *sy = tsy;
230    *sw = tsw;
231
232    return EINA_TRUE;
233 }
234
235 static void
236 _conformant_part_size_set(Evas_Object *obj, Evas_Object *sobj, Evas_Coord sx,
237                           Evas_Coord sy, Evas_Coord sw, Evas_Coord sh)
238 {
239    Evas_Coord cx, cy, cw, ch;
240    Evas_Coord part_height = 0, part_width = 0;
241
242    evas_object_geometry_get(obj, &cx, &cy, &cw, &ch);
243
244    /* Part overlapping with conformant */
245    if ((cx < (sx + sw)) && ((cx + cw) > sx)
246             && (cy < (sy + sh)) && ((cy + ch) > sy))
247      {
248         part_height = MIN((cy + ch), (sy + sh)) - MAX(cy, sy);
249         part_width = MIN((cx + cw), (sx + sw)) - MAX(cx, sx);
250      }
251
252    evas_object_size_hint_min_set(sobj, part_width, part_height);
253    evas_object_size_hint_max_set(sobj, part_width, part_height);
254 }
255
256 static void
257 _conformant_part_sizing_eval(Evas_Object *obj, Conformant_Part_Type part_type)
258 {
259    Ecore_X_Window zone = 0, xwin;
260    Evas_Object *top;
261    int sx = -1, sy = -1, sw = -1, sh = -1;
262    Widget_Data *wd = elm_widget_data_get(obj);
263
264    if (!wd) return;
265
266    top = elm_widget_top_get(obj);
267 #ifdef HAVE_ELEMENTARY_X
268    xwin = elm_win_xwindow_get(top);
269    if (xwin)
270      zone = ecore_x_e_illume_zone_get(xwin);
271 #endif
272
273    if (part_type & ELM_CONFORM_INDICATOR_PART)
274      {
275         if ((!_conformant_part_geometry_env_get("ILLUME_IND",
276                                                 &sx, &sy, &sw, &sh)) && (xwin))
277           {
278 #ifdef HAVE_ELEMENTARY_X
279            //No information of the indicator geometry, reset the geometry.
280              if (!ecore_x_e_illume_indicator_geometry_get(zone, &sx, &sy, &sw, &sh))
281                sx = sy = sw = sh = 0;
282 #else
283              ;
284 #endif
285           }
286         _conformant_part_size_set(obj, wd->shelf, sx, sy, sw, sh);
287      }
288    if (part_type & ELM_CONFORM_VIRTUAL_KEYPAD_PART)
289      {
290         if ((!_conformant_part_geometry_env_get("ILLUME_KBD",
291                                                 &sx, &sy, &sw, &sh)) && (xwin))
292           {
293 #ifdef HAVE_ELEMENTARY_X
294            //No information of the keyboard geometry, reset the geometry.
295            if (!ecore_x_e_illume_keyboard_geometry_get(zone, &sx, &sy, &sw, &sh))
296              sx = sy = sw = sh = 0;
297 #else
298              ;
299 #endif
300           }
301         _conformant_part_size_set(obj,wd->virtualkeypad, sx, sy, sw, sh);
302      }
303    if (part_type & ELM_CONFORM_SOFTKEY_PART)
304      {
305         if ((!_conformant_part_geometry_env_get("ILLUME_STK",
306                                                 &sx, &sy, &sw, &sh)) && (xwin))
307           {
308 #ifdef HAVE_ELEMENTARY_X
309            //No information of the softkey geometry, reset the geometry.
310            if (!ecore_x_e_illume_softkey_geometry_get(zone, &sx, &sy, &sw, &sh))
311              sx = sy = sw = sh = 0;
312 #else
313              ;
314 #endif
315           }
316         _conformant_part_size_set(obj, wd->panel, sx, sy, sw, sh);
317      }
318 }
319
320 static void
321 _swallow_conformant_parts(Evas_Object *obj)
322 {
323    Widget_Data *wd = elm_widget_data_get(obj);
324
325    wd->scroller = NULL;
326    if (!wd->shelf)
327      {
328         wd->shelf = evas_object_rectangle_add(evas_object_evas_get(obj));
329         elm_widget_sub_object_add(obj, wd->shelf);
330         evas_object_size_hint_min_set(wd->shelf, -1, 0);
331         evas_object_size_hint_max_set(wd->shelf, -1, 0);
332      }
333    else
334      _conformant_part_sizing_eval(obj, ELM_CONFORM_INDICATOR_PART);
335    evas_object_color_set(wd->shelf, 0, 0, 0, 0);
336    edje_object_part_swallow(wd->base, "elm.swallow.shelf", wd->shelf);
337
338    if (!wd->virtualkeypad)
339      {
340         wd->virtualkeypad = evas_object_rectangle_add(evas_object_evas_get(obj));
341         elm_widget_sub_object_add(obj, wd->virtualkeypad);
342         evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0);
343         evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0);
344      }
345    else
346      _conformant_part_sizing_eval(obj, ELM_CONFORM_VIRTUAL_KEYPAD_PART);
347    evas_object_color_set(wd->virtualkeypad, 0, 0, 0, 0);
348    edje_object_part_swallow(wd->base, "elm.swallow.virtualkeypad",
349                             wd->virtualkeypad);
350
351    if (!wd->sliding_win)
352      {
353         wd->sliding_win = evas_object_rectangle_add(evas_object_evas_get(obj));
354         elm_widget_sub_object_add(obj, wd->sliding_win);
355         evas_object_size_hint_min_set(wd->sliding_win, -1, 0);
356         evas_object_size_hint_max_set(wd->sliding_win, -1, 0);
357      }
358 #ifdef HAVE_ELEMENTARY_X
359    else
360      _conformant_part_sizing_eval(obj, ELM_CONFORM_SLIDING_WIN_PART);
361 #endif
362    evas_object_color_set(wd->sliding_win, 0, 0, 0, 0);
363
364    if (!wd->panel)
365      {
366         wd->panel = evas_object_rectangle_add(evas_object_evas_get(obj));
367         elm_widget_sub_object_add(obj, wd->panel);
368         evas_object_size_hint_min_set(wd->panel, -1, 0);
369         evas_object_size_hint_max_set(wd->panel, -1, 0);
370      }
371    else
372      _conformant_part_sizing_eval(obj, ELM_CONFORM_SOFTKEY_PART);
373    evas_object_color_set(wd->panel, 0, 0, 0, 0);
374    edje_object_part_swallow(wd->base, "elm.swallow.panel", wd->panel);
375 }
376
377 static void
378 _changed_size_hints(void *data, Evas *e __UNUSED__,
379                     Evas_Object *obj __UNUSED__,
380                     void *event_info __UNUSED__)
381 {
382    Widget_Data *wd = elm_widget_data_get(data);
383
384    if (!wd) return;
385    _sizing_eval(data);
386 }
387
388 static void
389 _sub_del(void *data, Evas_Object *obj __UNUSED__, void *event_info)
390 {
391    Widget_Data *wd = elm_widget_data_get(data);
392    Evas_Object *sub = event_info;
393 if (!wd) return;
394    if (sub == wd->content)
395      {
396         evas_object_event_callback_del_full(sub,
397                                             EVAS_CALLBACK_CHANGED_SIZE_HINTS,
398                                             _changed_size_hints, data);
399         wd->content = NULL;
400         _sizing_eval(data);
401      }
402 }
403
404 /* unused now - but meant to be for making sure the focused widget is always
405  * visible when the vkbd comes and goes by moving the conformant obj (and thus
406  * its children) to  show the focused widget (and if focus changes follow)
407
408 static Evas_Object *
409 _focus_object_get(const Evas_Object *obj)
410 {
411    Evas_Object *win, *foc;
412
413    win = elm_widget_top_get(obj);
414    if (!win) return NULL;
415    foc = elm_widget_top_get(win);
416 }
417
418 static void
419 _focus_object_region_get(const Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
420 {
421    evas_object_geometry_get(obj, x, y, w, h);
422 }
423
424 static void
425 _focus_change_del(void *data, Evas_Object *obj, void *event_info)
426 {
427    // called from toplevel when the focused window shanges
428 }
429
430 static void
431 _autoscroll_move(Evas_Object *obj)
432 {
433    // move conformant edje by delta to show focused widget
434 }
435
436 static void
437 _autoscroll_mode_enable(Evas_Object *obj)
438 {
439 // called when autoscroll mode should be on - content area smaller than
440 // its min size
441 // 1. get focused object
442 // 2. if not in visible conformant area calculate delta needed to
443 //    get it in
444 // 3. store delta and call _autoscroll_move() which either asanimates
445 //    or jumps right there
446 }
447
448 static void
449 _autoscroll_mode_disable(Evas_Object *obj)
450 {
451 // called when autoscroll mode should be off - set delta to 0 and
452 // call _autoscroll_move()
453 }
454  */
455
456 static void
457 _conformant_move_resize_event_cb(void *data __UNUSED__, Evas *e __UNUSED__,
458                                  Evas_Object *obj, void *event_info __UNUSED__)
459 {
460    Conformant_Part_Type part_type;
461    Widget_Data *wd = elm_widget_data_get(obj);
462
463    if (!wd) return;
464    part_type =  (ELM_CONFORM_INDICATOR_PART |
465                  ELM_CONFORM_SOFTKEY_PART |
466                  ELM_CONFORM_VIRTUAL_KEYPAD_PART |
467                  ELM_CONFORM_SLIDING_WIN_PART);
468    _conformant_part_sizing_eval(obj, part_type);
469 }
470
471 // showing the focused/important region.
472 static void
473 _content_resize_event_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj
474                          __UNUSED__, void *event_info __UNUSED__)
475 {
476    Evas_Object *conformant = (Evas_Object *)data;
477    Widget_Data *wd = elm_widget_data_get(conformant);
478
479    if (!wd) return;
480 #ifdef HAVE_ELEMENTARY_X
481    if ((wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
482             && (!wd->is_sliding_win_visible)) return;
483 #endif
484
485    if (wd->show_region_job) ecore_job_del(wd->show_region_job);
486    wd->show_region_job = ecore_job_add(_show_region_job, conformant);
487 }
488
489 static void
490 _show_region_job(void *data)
491 {
492    Evas_Object *focus_obj;
493    Evas_Object *conformant = (Evas_Object *)data;
494    Widget_Data *wd = elm_widget_data_get(conformant);
495
496    if (!wd) return;
497
498    focus_obj = elm_widget_focused_object_get(conformant);
499    if (focus_obj)
500      {
501         Evas_Coord x, y, w, h;
502
503         elm_widget_show_region_get(focus_obj, &x, &y, &w, &h);
504
505         if (h < _elm_config->finger_size)
506           h = _elm_config->finger_size;
507
508         elm_widget_show_region_set(focus_obj, x, y, w, h, EINA_TRUE);
509      }
510
511    wd->show_region_job = NULL;
512 }
513
514 #ifdef HAVE_ELEMENTARY_X
515 static void
516 _update_autoscroll_objs(void *data)
517 {
518    const char *type;
519    int i;
520    Evas_Object *sub, *top_scroller = NULL;
521    Evas_Object *conformant = (Evas_Object *)data;
522    Widget_Data *wd = elm_widget_data_get(data);
523
524    if (!wd) return;
525
526    sub = elm_widget_focused_object_get(conformant);
527    //Look up for Top most scroller in the Focus Object hierarchy inside Conformant.
528
529    while (sub)
530      {
531         type = elm_widget_type_get(sub);
532         if (!strcmp(type, "conformant")) break;
533         for (i = 0; i < SUB_TYPE_COUNT; i++)
534           if (!strcmp(type, sub_type[i]))
535             {
536                top_scroller = sub;
537                break;
538             }
539         sub = elm_object_parent_widget_get(sub);
540      }
541
542    //If the scroller got changed by app, replace it.
543    if (top_scroller != wd->scroller)
544      {
545         if (wd->scroller) evas_object_event_callback_del(wd->scroller,
546                                                    EVAS_CALLBACK_RESIZE,
547                                                    _content_resize_event_cb);
548         wd->scroller = top_scroller;
549         if (wd->scroller) evas_object_event_callback_add(wd->scroller,
550                                                    EVAS_CALLBACK_RESIZE,
551                                                    _content_resize_event_cb,
552                                                    data);
553      }
554 }
555
556 static Eina_Bool
557 _prop_change(void *data, int type __UNUSED__, void *event)
558 {
559    Ecore_X_Event_Window_Property *ev;
560    Widget_Data *wd = elm_widget_data_get(data);
561
562    if (!wd) return ECORE_CALLBACK_PASS_ON;
563    ev = event;
564    if (ev->atom == ECORE_X_ATOM_E_ILLUME_ZONE)
565      {
566         Conformant_Part_Type part_type;
567
568         part_type =  (ELM_CONFORM_INDICATOR_PART |
569                       ELM_CONFORM_SOFTKEY_PART |
570                       ELM_CONFORM_VIRTUAL_KEYPAD_PART |
571                       ELM_CONFORM_SLIDING_WIN_PART);
572         _conformant_part_sizing_eval(data, part_type);
573      }
574    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_INDICATOR_GEOMETRY)
575      _conformant_part_sizing_eval(data, ELM_CONFORM_INDICATOR_PART);
576    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SOFTKEY_GEOMETRY)
577      _conformant_part_sizing_eval(data, ELM_CONFORM_SOFTKEY_PART);
578    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_KEYBOARD_GEOMETRY)
579      _conformant_part_sizing_eval(data, ELM_CONFORM_VIRTUAL_KEYPAD_PART);
580    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_GEOMETRY)
581      _conformant_part_sizing_eval(data, ELM_CONFORM_SLIDING_WIN_PART);
582    else if (ev->atom == ECORE_X_ATOM_E_VIRTUAL_KEYBOARD_STATE)
583      {
584         Ecore_X_Window zone;
585
586         printf("Keyboard Geometry Changed\n");
587         zone = ecore_x_e_illume_zone_get(ev->win);
588         wd->vkb_state = ecore_x_e_virtual_keyboard_state_get(zone);
589         if (wd->vkb_state == ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF)
590           {
591              evas_object_size_hint_min_set(wd->virtualkeypad, -1, 0);
592              evas_object_size_hint_max_set(wd->virtualkeypad, -1, 0);
593           }
594         else
595           _update_autoscroll_objs(data);
596      }
597    else if (ev->atom == ECORE_X_ATOM_E_ILLUME_SLIDING_WIN_STATE)
598      {
599         Ecore_X_Window zone;
600
601         zone = ecore_x_e_illume_zone_get(ev->win);
602         wd->is_sliding_win_visible = ecore_x_e_illume_sliding_win_state_get(zone);
603
604         if (!wd->is_sliding_win_visible)
605           {
606              evas_object_size_hint_min_set(wd->sliding_win, -1, 0);
607              evas_object_size_hint_max_set(wd->sliding_win, -1, 0);
608           }
609         else
610           _update_autoscroll_objs(data);
611      }
612
613    return ECORE_CALLBACK_PASS_ON;
614 }
615 #endif
616
617 EAPI Evas_Object *
618 elm_conformant_add(Evas_Object *parent)
619 {
620    Evas_Object *obj;
621    Evas *e;
622    Widget_Data *wd;
623
624    ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
625
626    ELM_SET_WIDTYPE(widtype, "conformant");
627    elm_widget_type_set(obj, "conformant");
628    elm_widget_sub_object_add(parent, obj);
629    elm_widget_data_set(obj, wd);
630    elm_widget_del_pre_hook_set(obj, _del_pre_hook);
631    elm_widget_del_hook_set(obj, _del_hook);
632    elm_widget_theme_hook_set(obj, _theme_hook);
633    elm_widget_can_focus_set(obj, EINA_FALSE);
634    elm_widget_content_set_hook_set(obj, _content_set_hook);
635    elm_widget_content_get_hook_set(obj, _content_get_hook);
636    elm_widget_content_unset_hook_set(obj, _content_unset_hook);
637
638    wd->base = edje_object_add(e);
639    _elm_theme_object_set(obj, wd->base, "conformant", "base", "default");
640    elm_widget_resize_object_set(obj, wd->base);
641
642    _swallow_conformant_parts(obj);
643
644 #ifdef HAVE_ELEMENTARY_X
645    Evas_Object *top = elm_widget_top_get(obj);
646    Ecore_X_Window xwin = elm_win_xwindow_get(top);
647
648    if ((xwin) && (!elm_win_inlined_image_object_get(top)))
649      {
650         wd->prop_hdl = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
651                                                _prop_change, obj);
652         wd->vkb_state = ECORE_X_VIRTUAL_KEYBOARD_STATE_OFF;
653      }
654    // FIXME: get kbd region prop
655 #endif
656
657    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE,
658                                        _conformant_move_resize_event_cb, obj);
659    evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE,
660                                        _conformant_move_resize_event_cb, obj);
661    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
662
663
664    _mirrored_set(obj, elm_widget_mirrored_get(obj));
665    _sizing_eval(obj);
666    return obj;
667 }