note description: "EiffelVision popup window, GTK+ implementation" legal: "See notice at end of class." status: "See notice at end of class." date: "$Date$" revision: "$Revision$" class EV_POPUP_WINDOW_IMP inherit EV_POPUP_WINDOW_I undefine propagate_background_color, propagate_foreground_color, lock_update, unlock_update redefine interface end EV_WINDOW_IMP redefine interface, old_make, make, default_wm_decorations, client_area, show, hide, internal_enable_border, internal_disable_border, grab_keyboard_and_mouse, release_keyboard_and_mouse, allow_resize, forbid_resize, on_focus_changed end create make, initialize_with_shadow feature {NONE} -- Initialization old_make (an_interface: attached like interface) -- Connect interface and initialize `c_object'. do assign_interface (an_interface) end make -- Initialize `Current'. do client_area := {GTK}.gtk_event_box_new Precursor {EV_WINDOW_IMP} {GTK}.gtk_widget_show (client_area) {GTK}.gtk_container_add (c_object, client_area) if not override_redirect then -- {GTK}.gtk_window_set_type_hint (c_object, {EV_GTK_ENUMS}.gdk_window_type_hint_utility_enum) {GTK}.gtk_window_set_skip_taskbar_hint (c_object, True) end -- This completely disconnects the window from the window manager. if override_redirect then {GTK}.gdk_window_set_override_redirect ({GTK}.gtk_widget_struct_window (c_object), True) end disable_border disable_user_resize set_background_color ((create {EV_STOCK_COLORS}).black) set_is_initialized (True) end feature {EV_ANY_I} -- Implementation override_redirect: BOOLEAN = False on_focus_changed (a_has_focus: BOOLEAN) -- Called from focus intermediary agents when focus for `Current' has changed. -- if `a_has_focus' then `Current' has just received focus. do if override_redirect then if a_has_focus then app_implementation.set_focused_popup_window (Current) else app_implementation.set_focused_popup_window (Void) end end Precursor {EV_WINDOW_IMP} (a_has_focus) end grab_keyboard_and_mouse -- Perform a global mouse and keyboard grab. do if not is_disconnected_from_window_manager then Precursor end end release_keyboard_and_mouse -- Release mouse and keyboard grab. do if not is_disconnected_from_window_manager then Precursor end end feature {NONE} -- implementation allow_resize -- Allow user resizing of `Current'. do internal_enable_border -- {GTK}.gtk_window_set_resizable (c_object, True) end forbid_resize -- Forbid user resizing of `Current'. do -- {GTK}.gtk_window_set_resizable (c_object, False) end border_width: INTEGER = 1 -- Border width of `Current'. internal_enable_border -- Ensure a border is displayed around Current. do {GTK}.gtk_container_set_border_width (c_object, border_width) end internal_disable_border -- Ensure no border is displayed around Current. do {GTK}.gtk_container_set_border_width (c_object, 0) end feature {EV_APPLICATION_IMP} -- Implementation show -- Map the Window to the screen. do {GTK}.gtk_window_set_accept_focus (c_object, not is_disconnected_from_window_manager) Precursor if override_redirect then if not has_focus then grab_keyboard_and_mouse end end end hide -- Unmap the Window from the screen. do if override_redirect then if has_focus then release_keyboard_and_mouse -- We reset the focused popup window here in case hide is called as part of destroy -- in which case the focus out event will not be called. if is_in_destroy then app_implementation.set_focused_popup_window (Void) end end end Precursor; end handle_mouse_button_event (a_type: INTEGER_32; a_button: INTEGER_32; a_screen_x, a_screen_y: INTEGER_32) -- A mouse event has occurred. do if override_redirect then if a_type = {GTK}.gdk_button_press_enum then if a_screen_x >= x_position and then a_screen_x <= (x_position + width) and then a_screen_y >= y_position and then a_screen_y <= (y_position + height) then grab_keyboard_and_mouse else -- Emulate WM handling when clicking off window. if has_focus then release_keyboard_and_mouse end end end end end feature {NONE} -- Implementation default_wm_decorations: INTEGER -- Default Window Manager decorations of `Current'. do Result := 0 end client_area: POINTER -- Container area of `Current'. feature {EV_ANY, EV_ANY_I} -- Implementation interface: detachable EV_POPUP_WINDOW note option: stable attribute end; -- Provides a common user interface to possibly dependent -- functionality implemented by `Current'. note copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class EV_POPUP_WINDOW_IMP