efl_ui_win: add 'exit_on_close' property and unit test
authorMike Blumenkrantz <zmike@samsung.com>
Thu, 31 Jan 2019 16:54:58 +0000 (11:54 -0500)
committerJongmin Lee <jm105.lee@samsung.com>
Wed, 6 Feb 2019 22:20:10 +0000 (07:20 +0900)
Summary:
this property can enable the associated window to quit the main loop with
the passed exit code when the window is destroyed

@feature
fix T5494

Depends on D7594

Reviewers: cedric

Reviewed By: cedric

Subscribers: #reviewers, #committers

Tags: #efl

Maniphest Tasks: T5494

Differential Revision: https://phab.enlightenment.org/D7595

src/lib/elementary/efl_ui_win.c
src/lib/elementary/efl_ui_win.eo
src/tests/elementary/elm_test_win.c

index 88cd76c..b189a87 100644 (file)
@@ -315,6 +315,8 @@ struct _Efl_Ui_Win_Data
       Eina_Bool    ctor : 1; /**< legacy constructor: elm_win~add */
    } legacy;
 
+   Eina_Value exit_on_close;
+
    Eina_Bool    first_draw : 1;
    Eina_Bool    deferred_resize_job : 1;
    Eina_Bool    urgent : 1;
@@ -3555,7 +3557,9 @@ _efl_ui_win_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Win_Data *sd)
 
    efl_canvas_group_del(efl_super(obj, MY_CLASS));
 
-   if (!_elm_win_list)
+   if (eina_value_type_get(&sd->exit_on_close))
+     efl_loop_quit(efl_loop_get(obj), sd->exit_on_close);
+   else if (!_elm_win_list)
      {
        if (elm_policy_get(ELM_POLICY_QUIT) == ELM_POLICY_QUIT_LAST_WINDOW_CLOSED)
          _elm_win_flush_cache_and_exit(obj);
@@ -6939,6 +6943,23 @@ _efl_ui_win_icon_object_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
    return sd->icon;
 }
 
+EOLIAN static const Eina_Value *
+_efl_ui_win_exit_on_close_get(const Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd)
+{
+   return &sd->exit_on_close;
+}
+
+EOLIAN static void
+_efl_ui_win_exit_on_close_set(Eo *obj EINA_UNUSED, Efl_Ui_Win_Data *sd, const Eina_Value *exit_code)
+{
+   const Eina_Value_Type *type = eina_value_type_get(exit_code);
+
+   if (type)
+     eina_value_copy(exit_code, &sd->exit_on_close);
+   else
+     eina_value_flush(&sd->exit_on_close);
+}
+
 /* Only for C API */
 EAPI void
 elm_win_autodel_set(Eo *obj, Eina_Bool autodel)
index 9339f70..c7ee1ee 100644 (file)
@@ -332,6 +332,19 @@ class Efl.Ui.Win extends Efl.Ui.Widget implements Efl.Canvas.Scene, Efl.Access.W
                               itself when closed.]]
          }
       }
+      @property exit_on_close {
+         [[Enable quitting the main loop when this window is closed.
+
+           When set, the window's loop object will exit using the passed exit code if the
+           window is closed.
+
+           The Eina.Value passed should be $EMPTY to unset this state or an int value to be
+           used as the exit code.
+         ]]
+         values {
+            exit_code: const(any_value_ptr); [[The exit code to use when exiting]]
+         }
+      }
       @property icon_object {
          set {
             [[Set a window object's icon.
index 2b0ec55..0c34691 100644 (file)
@@ -208,6 +208,26 @@ EFL_START_TEST(elm_win_policy_quit_last_window_hidden)
 }
 EFL_END_TEST
 
+EFL_START_TEST(elm_win_test_exit_on_close)
+{
+   Eo *win = win_add(NULL, "win", ELM_WIN_BASIC);
+   Eina_Value val, *exit_val;
+   int code;
+
+   val = eina_value_int_init(66);
+   efl_ui_win_exit_on_close_set(win, &val);
+   efl_gfx_entity_visible_set(win, EINA_TRUE);
+
+   Eina_Bool fail_flag = EINA_FALSE;
+   ecore_timer_add(_timeout1, _timer_del_window_cb, win);
+   ecore_timer_add(_timeout_fail, _timer_fail_flag_cb, &fail_flag);
+
+   exit_val = efl_loop_begin(efl_loop_get(win));
+   ck_assert(eina_value_int_get(exit_val, &code));
+   ck_assert_int_eq(code, 66);
+}
+EFL_END_TEST
+
 EFL_START_TEST(elm_win_autohide_and_policy_quit_last_window_hidden)
 {
    elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_HIDDEN);
@@ -436,6 +456,7 @@ void elm_test_win(TCase *tc)
    tcase_add_test(tc, elm_atspi_role_get);
    tcase_add_test(tc, elm_atspi_component_screen_position);
    tcase_add_test(tc, elm_win_policy_quit_last_window_hidden);
+   tcase_add_test(tc, elm_win_test_exit_on_close);
    tcase_add_test(tc, elm_win_test_app_exit_on_windows_close);
    tcase_add_test(tc, efl_ui_win_multi_touch_inputs);
 #ifdef HAVE_ELEMENTARY_X