1 #ifndef VIEW_IMPL_HPP 2 #define VIEW_IMPL_HPP 3 4 #include <wayfire/nonstd/safe-list.hpp> 5 #include <wayfire/view.hpp> 6 #include <wayfire/opengl.hpp> 7 8 #include "surface-impl.hpp" 9 #include <wayfire/nonstd/wlroots-full.hpp> 10 11 // for emit_map_*() 12 #include <wayfire/compositor-view.hpp> 13 #include <wayfire/compositor-surface.hpp> 14 15 struct wlr_seat; 16 namespace wf 17 { 18 struct sublayer_t; 19 struct view_transform_block_t : public noncopyable_t 20 { 21 std::string plugin_name = ""; 22 std::unique_ptr<wf::view_transformer_t> transform; 23 wf::framebuffer_t fb; 24 25 view_transform_block_t(); 26 ~view_transform_block_t(); 27 }; 28 29 /** Private data used by the default view_interface_t implementation */ 30 class view_interface_t::view_priv_impl 31 { 32 public: 33 /** 34 * A view is alive as long as it is possible for it to become mapped in the 35 * future. For wlr views, this means that their role object hasn't been 36 * destroyed and they still have the internal surface reference. 37 */ 38 bool is_alive = true; 39 /** Reference count to the view */ 40 int ref_cnt = 0; 41 42 bool keyboard_focus_enabled = true; 43 44 /** 45 * Calculate the windowed geometry relative to the output's workarea. 46 */ 47 wf::geometry_t calculate_windowed_geometry(wf::output_t *output); 48 49 /** 50 * Update the stored window geometry and workarea, if the current view 51 * state is not-tiled and not-moving. 52 */ 53 void update_windowed_geometry(wayfire_view self, wf::geometry_t geometry); 54 55 /* those two point to the same object. Two fields are used to avoid 56 * constant casting to and from types */ 57 surface_interface_t *decoration = NULL; 58 wf::decorator_frame_t_t *frame = NULL; 59 60 uint32_t edges = 0; 61 int in_continuous_move = 0; 62 int in_continuous_resize = 0; 63 int visibility_counter = 1; 64 65 wf::safe_list_t<std::shared_ptr<view_transform_block_t>> transforms; 66 67 struct offscreen_buffer_t : public wf::framebuffer_t 68 { 69 wf::region_t cached_damage; validwf::view_interface_t::view_priv_impl::offscreen_buffer_t70 bool valid() 71 { 72 return this->fb != (uint32_t)-1; 73 } 74 } offscreen_buffer; 75 76 wlr_box minimize_hint = {0, 0, 0, 0}; 77 78 /** The sublayer of the view. For workspace-manager. */ 79 nonstd::observer_ptr<sublayer_t> sublayer; 80 /* Promoted to the fullscreen layer? For workspace-manager. */ 81 bool is_promoted = false; 82 83 private: 84 /** Last geometry the view has had in non-tiled and non-fullscreen state. 85 * -1 as width/height means that no such geometry has been stored. */ 86 wf::geometry_t last_windowed_geometry = {0, 0, -1, -1}; 87 88 /** 89 * The workarea when last_windowed_geometry was stored. This is used 90 * for ex. when untiling a view to determine its geometry relative to the 91 * (potentially changed) workarea of its output. 92 */ 93 wf::geometry_t windowed_geometry_workarea = {0, 0, -1, -1}; 94 }; 95 96 /** 97 * Damage the given box, assuming the damage belongs to the given view. 98 * The given box is assumed to have been transformed with the view's 99 * transformers. 100 * 101 * The main difference with directly damaging the output is that this will 102 * add the damage to all workspaces the view is visible on, in case of shell 103 * views. 104 */ 105 void view_damage_raw(wayfire_view view, const wlr_box& box); 106 107 /** 108 * Implementation of a view backed by a wlr_* shell struct. 109 */ 110 class wlr_view_t : 111 public wlr_surface_base_t, 112 public view_interface_t 113 { 114 public: 115 wlr_view_t(); ~wlr_view_t()116 virtual ~wlr_view_t() 117 {} 118 119 /* Functions which are shell-independent */ 120 virtual void set_role(view_role_t new_role) override final; 121 122 virtual std::string get_app_id() override final; 123 virtual std::string get_title() override final; 124 virtual wf::region_t get_transformed_opaque_region() override; 125 126 /* Functions which are further specialized for the different shells */ 127 virtual void move(int x, int y) override; 128 virtual wf::geometry_t get_wm_geometry() override; 129 virtual wf::geometry_t get_output_geometry() override; 130 131 virtual wlr_surface *get_keyboard_focus_surface() override; 132 133 virtual bool should_be_decorated() override; 134 virtual void set_decoration_mode(bool use_csd); 135 virtual void set_output(wf::output_t*) override; 136 bool has_client_decoration = true; 137 138 protected: 139 std::string title, app_id; 140 /** Used by view implementations when the app id changes */ 141 void handle_app_id_changed(std::string new_app_id); 142 /** Used by view implementations when the title changes */ 143 void handle_title_changed(std::string new_title); 144 /* Update the minimize hint */ 145 void handle_minimize_hint(wf::surface_interface_t *relative_to, 146 const wlr_box& hint); 147 148 /** 149 * The bounding box of the view the last time it was rendered. 150 * 151 * This is used to damage the view when it is resized, because when a 152 * transformer changes because the view is resized, we can't reliably 153 * calculate the old view region to damage. 154 */ 155 wf::geometry_t last_bounding_box{0, 0, 0, 0}; 156 157 /** 158 * Adjust the view position when resizing the view so that its apparent 159 * position doesn't change when resizing. 160 */ 161 void adjust_anchored_edge(wf::dimensions_t new_size); 162 163 /** The output geometry of the view */ 164 wf::geometry_t geometry{100, 100, 0, 0}; 165 166 /** Set the view position and optionally send the geometry changed signal 167 * @param old_geometry The geometry to report as previous, in case the 168 * signal is sent. */ 169 virtual void set_position(int x, int y, wf::geometry_t old_geometry, 170 bool send_geometry_signal); 171 /** Update the view size to the actual dimensions of its surface */ 172 virtual void update_size(); 173 174 /** Last request to the client */ 175 wf::dimensions_t last_size_request = {0, 0}; 176 virtual bool should_resize_client(wf::dimensions_t request, 177 wf::dimensions_t current_size); 178 179 virtual void commit() override; 180 virtual void map(wlr_surface *surface) override; 181 virtual void unmap() override; 182 183 /* Handle the destruction of the underlying wlroots object */ 184 virtual void destroy(); 185 186 /* 187 * wlr_foreign_toplevel_v1 implementation functions 188 */ 189 190 /* The toplevel is created by the individual view's mapping functions, 191 * i.e in xdg-shell, xwayland, etc. 192 * The handle is automatically destroyed when the view is unmapped */ 193 wlr_foreign_toplevel_handle_v1 *toplevel_handle = NULL; 194 195 wf::wl_listener_wrapper toplevel_handle_v1_maximize_request, 196 toplevel_handle_v1_activate_request, 197 toplevel_handle_v1_minimize_request, 198 toplevel_handle_v1_set_rectangle_request, 199 toplevel_handle_v1_close_request; 200 201 /* Create/destroy the toplevel_handle */ 202 virtual void create_toplevel(); 203 virtual void destroy_toplevel(); 204 205 /* The following are no-op if toplevel_handle == NULL */ 206 virtual void toplevel_send_title(); 207 virtual void toplevel_send_app_id(); 208 virtual void toplevel_send_state(); 209 virtual void toplevel_update_output(wf::output_t *output, bool enter); 210 211 virtual void desktop_state_updated() override; 212 213 public: 214 /* Just pass to the default wlr surface implementation */ is_mapped() const215 virtual bool is_mapped() const override 216 { 217 return _is_mapped(); 218 } 219 get_size() const220 virtual wf::dimensions_t get_size() const override 221 { 222 return _get_size(); 223 } 224 simple_render(const wf::framebuffer_t & fb,int x,int y,const wf::region_t & damage)225 virtual void simple_render(const wf::framebuffer_t& fb, int x, int y, 226 const wf::region_t& damage) override 227 { 228 _simple_render(fb, x, y, damage); 229 } 230 }; 231 232 /** Emit the map signal for the given view */ 233 void emit_view_map_signal(wayfire_view view, bool has_position); 234 void emit_ping_timeout_signal(wayfire_view view); 235 236 wf::surface_interface_t *wf_surface_from_void(void *handle); 237 wf::view_interface_t *wf_view_from_void(void *handle); 238 239 void init_xdg_shell(); 240 void init_xwayland(); 241 void init_layer_shell(); 242 243 std::string xwayland_get_display(); 244 void xwayland_update_default_cursor(); 245 246 /* Ensure that the given surface is on top of the Xwayland stack order. */ 247 void xwayland_bring_to_front(wlr_surface *surface); 248 249 /* Get the current Xwayland drag icon, if it exists. */ 250 wayfire_view get_xwayland_drag_icon(); 251 252 void init_desktop_apis(); 253 } 254 255 #endif /* end of include guard: VIEW_IMPL_HPP */ 256