Parcourir la source

LibCore+LibGUI: Switch to using AK::is and AK::downcast

Andreas Kling il y a 5 ans
Parent
commit
e0b8b4ac67

+ 1 - 1
Applications/Browser/InspectorWidget.cpp

@@ -42,7 +42,7 @@ void InspectorWidget::set_inspected_node(Web::Node* node)
 {
     m_document->set_inspected_node(node);
     if (node && node->is_element()) {
-        auto& element = Web::to<Web::Element>(*node);
+        auto& element = downcast<Web::Element>(*node);
         if (element.resolved_style()) {
             m_style_table_view->set_model(Web::StylePropertiesModel::create(*element.resolved_style()));
             m_computed_style_table_view->set_model(Web::StylePropertiesModel::create(*element.computed_style()));

+ 3 - 5
DevTools/HackStudio/EditorWrapper.h

@@ -55,8 +55,6 @@ private:
     RefPtr<Editor> m_editor;
 };
 
-template<>
-inline bool Core::is<EditorWrapper>(const Core::Object& object)
-{
-    return !strcmp(object.class_name(), "EditorWrapper");
-}
+AK_BEGIN_TYPE_TRAITS(EditorWrapper)
+static bool is_type(const Core::Object& object) { return !strcmp(object.class_name(), "EditorWrapper"); }
+AK_END_TYPE_TRAITS()

+ 5 - 18
Libraries/LibCore/Object.h

@@ -31,6 +31,7 @@
 #include <AK/Noncopyable.h>
 #include <AK/NonnullRefPtrVector.h>
 #include <AK/String.h>
+#include <AK/TypeCasts.h>
 #include <AK/Weakable.h>
 #include <LibCore/Forward.h>
 
@@ -147,8 +148,8 @@ protected:
     // NOTE: You may get child events for children that are not yet fully constructed!
     virtual void child_event(ChildEvent&);
 
-    virtual void did_begin_inspection() {}
-    virtual void did_end_inspection() {}
+    virtual void did_begin_inspection() { }
+    virtual void did_end_inspection() { }
 
 private:
     Object* m_parent { nullptr };
@@ -159,29 +160,15 @@ private:
     NonnullRefPtrVector<Object> m_children;
 };
 
-template<typename T>
-inline bool is(const Object&) { return false; }
-
-template<typename T>
-inline T& to(Object& object)
-{
-    ASSERT(is<typename RemoveConst<T>::Type>(object));
-    return static_cast<T&>(object);
-}
-
-template<typename T>
-inline const T& to(const Object& object)
-{
-    ASSERT(is<typename RemoveConst<T>::Type>(object));
-    return static_cast<const T&>(object);
 }
 
+namespace Core {
 template<typename T, typename Callback>
 inline void Object::for_each_child_of_type(Callback callback)
 {
     for_each_child([&](auto& child) {
         if (is<T>(child))
-            return callback(to<T>(child));
+            return callback(downcast<T>(child));
         return IterationDecision::Continue;
     });
 }

+ 3 - 7
Libraries/LibGUI/AbstractButton.h

@@ -91,10 +91,6 @@ private:
 
 }
 
-template<>
-inline bool Core::is<GUI::AbstractButton>(const Core::Object& object)
-{
-    if (!is<GUI::Widget>(object))
-        return false;
-    return to<GUI::Widget>(object).is_abstract_button();
-}
+AK_BEGIN_TYPE_TRAITS(GUI::AbstractButton)
+static bool is_type(const Core::Object& object) { return is<GUI::Widget>(object) && downcast<GUI::Widget>(object).is_abstract_button(); }
+AK_END_TYPE_TRAITS()

+ 2 - 2
Libraries/LibGUI/Action.cpp

@@ -152,9 +152,9 @@ Action::Action(const StringView& text, const Shortcut& shortcut, RefPtr<Gfx::Bit
     , m_shortcut(shortcut)
     , m_checkable(checkable)
 {
-    if (parent && Core::is<Widget>(*parent)) {
+    if (parent && is<Widget>(*parent)) {
         m_scope = ShortcutScope::WidgetLocal;
-    } else if (parent && Core::is<Window>(*parent)) {
+    } else if (parent && is<Window>(*parent)) {
         m_scope = ShortcutScope::WindowLocal;
     } else {
         m_scope = ShortcutScope::ApplicationGlobal;

+ 20 - 22
Libraries/LibGUI/Action.h

@@ -42,23 +42,23 @@
 namespace GUI {
 
 namespace CommonActions {
-    NonnullRefPtr<Action> make_open_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_save_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_undo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_redo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_cut_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_copy_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_paste_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_delete_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_move_to_front_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_move_to_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_fullscreen_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_quit_action(Function<void(Action&)>);
-    NonnullRefPtr<Action> make_go_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_go_forward_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_go_home_action(Function<void(Action&)> callback, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_reload_action(Function<void(Action&)>, Core::Object* parent = nullptr);
-    NonnullRefPtr<Action> make_select_all_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_open_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_save_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_undo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_redo_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_cut_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_copy_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_paste_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_delete_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_move_to_front_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_move_to_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_fullscreen_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_quit_action(Function<void(Action&)>);
+NonnullRefPtr<Action> make_go_back_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_go_forward_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_go_home_action(Function<void(Action&)> callback, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_reload_action(Function<void(Action&)>, Core::Object* parent = nullptr);
+NonnullRefPtr<Action> make_select_all_action(Function<void(Action&)>, Core::Object* parent = nullptr);
 };
 
 class Action final : public Core::Object {
@@ -168,8 +168,6 @@ private:
 
 }
 
-template<>
-inline bool Core::is<GUI::Action>(const Core::Object& object)
-{
-    return object.is_action();
-}
+AK_BEGIN_TYPE_TRAITS(GUI::Action)
+static bool is_type(const Core::Object& object) { return object.is_action(); }
+AK_END_TYPE_TRAITS()

+ 1 - 1
Libraries/LibGUI/RadioButton.cpp

@@ -74,7 +74,7 @@ void RadioButton::for_each_in_group(Callback callback)
     if (!parent())
         return;
     parent()->for_each_child_of_type<RadioButton>([&](auto& child) {
-        return callback(static_cast<RadioButton&>(child));
+        return callback(downcast<RadioButton>(child));
     });
 }
 

+ 3 - 7
Libraries/LibGUI/RadioButton.h

@@ -55,10 +55,6 @@ private:
 
 }
 
-template<>
-inline bool Core::is<GUI::RadioButton>(const Core::Object& object)
-{
-    if (!is<GUI::Widget>(object))
-        return false;
-    return to<GUI::Widget>(object).is_radio_button();
-}
+AK_BEGIN_TYPE_TRAITS(GUI::RadioButton)
+static bool is_type(const Core::Object& object) { return is<GUI::Widget>(object) && downcast<GUI::Widget>(object).is_radio_button(); }
+AK_END_TYPE_TRAITS()

+ 2 - 2
Libraries/LibGUI/StackWidget.cpp

@@ -63,9 +63,9 @@ void StackWidget::resize_event(ResizeEvent& event)
 
 void StackWidget::child_event(Core::ChildEvent& event)
 {
-    if (!event.child() || !Core::is<Widget>(*event.child()))
+    if (!event.child() || !is<Widget>(*event.child()))
         return Widget::child_event(event);
-    auto& child = Core::to<Widget>(*event.child());
+    auto& child = downcast<Widget>(*event.child());
     if (event.type() == Event::ChildAdded) {
         if (!m_active_widget)
             set_active_widget(&child);

+ 2 - 2
Libraries/LibGUI/TabWidget.cpp

@@ -102,9 +102,9 @@ Gfx::IntRect TabWidget::child_rect_for_size(const Gfx::IntSize& size) const
 
 void TabWidget::child_event(Core::ChildEvent& event)
 {
-    if (!event.child() || !Core::is<Widget>(*event.child()))
+    if (!event.child() || !is<Widget>(*event.child()))
         return Widget::child_event(event);
-    auto& child = Core::to<Widget>(*event.child());
+    auto& child = downcast<Widget>(*event.child());
     if (event.type() == Event::ChildAdded) {
         if (!m_active_widget)
             set_active_widget(&child);

+ 11 - 11
Libraries/LibGUI/Widget.cpp

@@ -109,24 +109,24 @@ Widget::~Widget()
 void Widget::child_event(Core::ChildEvent& event)
 {
     if (event.type() == Event::ChildAdded) {
-        if (event.child() && Core::is<Widget>(*event.child()) && layout()) {
+        if (event.child() && is<Widget>(*event.child()) && layout()) {
             if (event.insertion_before_child() && event.insertion_before_child()->is_widget())
-                layout()->insert_widget_before(Core::to<Widget>(*event.child()), Core::to<Widget>(*event.insertion_before_child()));
+                layout()->insert_widget_before(downcast<Widget>(*event.child()), downcast<Widget>(*event.insertion_before_child()));
             else
-                layout()->add_widget(Core::to<Widget>(*event.child()));
+                layout()->add_widget(downcast<Widget>(*event.child()));
         }
-        if (window() && event.child() && Core::is<Widget>(*event.child()))
-            window()->did_add_widget({}, Core::to<Widget>(*event.child()));
+        if (window() && event.child() && is<Widget>(*event.child()))
+            window()->did_add_widget({}, downcast<Widget>(*event.child()));
     }
     if (event.type() == Event::ChildRemoved) {
         if (layout()) {
-            if (event.child() && Core::is<Widget>(*event.child()))
-                layout()->remove_widget(Core::to<Widget>(*event.child()));
+            if (event.child() && is<Widget>(*event.child()))
+                layout()->remove_widget(downcast<Widget>(*event.child()));
             else
                 invalidate_layout();
         }
-        if (window() && event.child() && Core::is<Widget>(*event.child()))
-            window()->did_remove_widget({}, Core::to<Widget>(*event.child()));
+        if (window() && event.child() && is<Widget>(*event.child()))
+            window()->did_remove_widget({}, downcast<Widget>(*event.child()));
         update();
     }
     return Core::Object::child_event(event);
@@ -470,9 +470,9 @@ Gfx::IntRect Widget::screen_relative_rect() const
 Widget* Widget::child_at(const Gfx::IntPoint& point) const
 {
     for (int i = children().size() - 1; i >= 0; --i) {
-        if (!Core::is<Widget>(children()[i]))
+        if (!is<Widget>(children()[i]))
             continue;
-        auto& child = Core::to<Widget>(children()[i]);
+        auto& child = downcast<Widget>(children()[i]);
         if (!child.is_visible())
             continue;
         if (child.content_rect().contains(point))

+ 13 - 15
Libraries/LibGUI/Widget.h

@@ -40,12 +40,6 @@
     extern WidgetClassRegistration registration_##class_name; \
     WidgetClassRegistration registration_##class_name(#class_name, []() { return class_name::construct(); });
 
-template<>
-inline bool Core::is<GUI::Widget>(const Core::Object& object)
-{
-    return object.is_widget();
-}
-
 namespace GUI {
 
 enum class SizePolicy {
@@ -249,8 +243,8 @@ public:
     void for_each_child_widget(Callback callback)
     {
         for_each_child([&](auto& child) {
-            if (Core::is<Widget>(child))
-                return callback(Core::to<Widget>(child));
+            if (is<Widget>(child))
+                return callback(downcast<Widget>(child));
             return IterationDecision::Continue;
         });
     }
@@ -278,9 +272,9 @@ public:
 protected:
     Widget();
 
-    virtual void custom_layout() {}
-    virtual void did_change_font() {}
-    virtual void did_layout() {}
+    virtual void custom_layout() { }
+    virtual void did_change_font() { }
+    virtual void did_layout() { }
     virtual void paint_event(PaintEvent&);
     virtual void resize_event(ResizeEvent&);
     virtual void show_event(ShowEvent&);
@@ -347,14 +341,18 @@ private:
 
 inline Widget* Widget::parent_widget()
 {
-    if (parent() && Core::is<Widget>(*parent()))
-        return &Core::to<Widget>(*parent());
+    if (parent() && is<Widget>(*parent()))
+        return &downcast<Widget>(*parent());
     return nullptr;
 }
 inline const Widget* Widget::parent_widget() const
 {
-    if (parent() && Core::is<Widget>(*parent()))
-        return &Core::to<const Widget>(*parent());
+    if (parent() && is<Widget>(*parent()))
+        return &downcast<const Widget>(*parent());
     return nullptr;
 }
 }
+
+AK_BEGIN_TYPE_TRAITS(GUI::Widget)
+static bool is_type(const Core::Object& object) { return object.is_widget(); }
+AK_END_TYPE_TRAITS()

+ 3 - 5
Libraries/LibGUI/Window.h

@@ -266,8 +266,6 @@ private:
 
 }
 
-template<>
-inline bool Core::is<GUI::Window>(const Core::Object& object)
-{
-    return object.is_window();
-}
+AK_BEGIN_TYPE_TRAITS(GUI::Window)
+static bool is_type(const Core::Object& object) { return object.is_window(); }
+AK_END_TYPE_TRAITS()

+ 272 - 0
Libraries/LibGUI/Window.h.orig

@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <AK/Function.h>
+#include <AK/String.h>
+#include <AK/WeakPtr.h>
+#include <LibCore/Object.h>
+#include <LibGUI/Forward.h>
+#include <LibGUI/WindowType.h>
+#include <LibGfx/Color.h>
+#include <LibGfx/Forward.h>
+#include <LibGfx/Rect.h>
+
+namespace GUI {
+
+enum class StandardCursor {
+    None = 0,
+    Arrow,
+    IBeam,
+    ResizeHorizontal,
+    ResizeVertical,
+    ResizeDiagonalTLBR,
+    ResizeDiagonalBLTR,
+    ResizeColumn,
+    ResizeRow,
+    Hand,
+    Help,
+    Drag,
+    Move,
+    Wait,
+};
+
+class Window : public Core::Object {
+    C_OBJECT(Window)
+public:
+    virtual ~Window() override;
+
+    static Window* from_window_id(int);
+
+    bool is_modal() const { return m_modal; }
+    void set_modal(bool);
+
+    bool is_fullscreen() const { return m_fullscreen; }
+    void set_fullscreen(bool);
+
+    bool is_maximized() const;
+
+    bool is_frameless() const { return m_frameless; }
+    void set_frameless(bool frameless) { m_frameless = frameless; }
+
+    bool is_resizable() const { return m_resizable; }
+    void set_resizable(bool resizable) { m_resizable = resizable; }
+
+    bool is_minimizable() const { return m_minimizable; }
+    void set_minimizable(bool minimizable) { m_minimizable = minimizable; }
+
+    void set_double_buffering_enabled(bool);
+    void set_has_alpha_channel(bool);
+    void set_opacity(float);
+    void set_window_type(WindowType);
+
+    int window_id() const { return m_window_id; }
+
+    String title() const;
+    void set_title(const StringView&);
+
+    Color background_color() const { return m_background_color; }
+    void set_background_color(Color color) { m_background_color = color; }
+
+    enum class CloseRequestDecision {
+        StayOpen,
+        Close,
+    };
+
+    Function<CloseRequestDecision()> on_close_request;
+    Function<void(bool is_active_input)> on_active_input_change;
+    Function<void(const bool is_active)> on_activity_change;
+
+    int x() const { return rect().x(); }
+    int y() const { return rect().y(); }
+    int width() const { return rect().width(); }
+    int height() const { return rect().height(); }
+
+    Gfx::IntRect rect() const;
+    Gfx::IntSize size() const { return rect().size(); }
+    void set_rect(const Gfx::IntRect&);
+    void set_rect(int x, int y, int width, int height) { set_rect({ x, y, width, height }); }
+
+    Gfx::IntPoint position() const { return rect().location(); }
+
+    void move_to(int x, int y) { move_to({ x, y }); }
+    void move_to(const Gfx::IntPoint& point) { set_rect({ point, size() }); }
+
+    void resize(int width, int height) { resize({ width, height }); }
+    void resize(const Gfx::IntSize& size) { set_rect({ position(), size }); }
+
+    virtual void event(Core::Event&) override;
+
+    bool is_visible() const;
+    bool is_active() const { return m_is_active; }
+    bool is_active_input() const { return m_is_active_input; }
+
+    bool is_accessory() const { return m_accessory; }
+    void set_accessory(bool accessory) { m_accessory = accessory; }
+
+    void show();
+    void hide();
+    virtual void close();
+    void move_to_front();
+
+    void start_wm_resize();
+
+    Widget* main_widget() { return m_main_widget; }
+    const Widget* main_widget() const { return m_main_widget; }
+    void set_main_widget(Widget*);
+
+    template<class T, class... Args>
+    inline T& set_main_widget(Args&&... args)
+    {
+        auto widget = T::construct(forward<Args>(args)...);
+        set_main_widget(widget.ptr());
+        return *widget;
+    }
+
+    Widget* focused_widget() { return m_focused_widget; }
+    const Widget* focused_widget() const { return m_focused_widget; }
+    void set_focused_widget(Widget*);
+
+    void update();
+    void update(const Gfx::IntRect&);
+
+    void set_global_cursor_tracking_widget(Widget*);
+    Widget* global_cursor_tracking_widget() { return m_global_cursor_tracking_widget.ptr(); }
+    const Widget* global_cursor_tracking_widget() const { return m_global_cursor_tracking_widget.ptr(); }
+
+    void set_automatic_cursor_tracking_widget(Widget*);
+    Widget* automatic_cursor_tracking_widget() { return m_automatic_cursor_tracking_widget.ptr(); }
+    const Widget* automatic_cursor_tracking_widget() const { return m_automatic_cursor_tracking_widget.ptr(); }
+
+    Widget* hovered_widget() { return m_hovered_widget.ptr(); }
+    const Widget* hovered_widget() const { return m_hovered_widget.ptr(); }
+    void set_hovered_widget(Widget*);
+
+    Gfx::Bitmap* front_bitmap() { return m_front_bitmap.ptr(); }
+    Gfx::Bitmap* back_bitmap() { return m_back_bitmap.ptr(); }
+
+    Gfx::IntSize size_increment() const { return m_size_increment; }
+    void set_size_increment(const Gfx::IntSize&);
+    Gfx::IntSize base_size() const { return m_base_size; }
+    void set_base_size(const Gfx::IntSize&);
+
+    void set_override_cursor(StandardCursor);
+    void set_override_cursor(const Gfx::Bitmap&);
+
+    void set_icon(const Gfx::Bitmap*);
+    void apply_icon();
+    const Gfx::Bitmap* icon() const { return m_icon.ptr(); }
+
+    Vector<Widget*> focusable_widgets() const;
+
+    virtual void save_to(AK::JsonObject&) override;
+
+    void schedule_relayout();
+
+    static void for_each_window(Badge<WindowServerConnection>, Function<void(Window&)>);
+    static void update_all_windows(Badge<WindowServerConnection>);
+    void notify_state_changed(Badge<WindowServerConnection>, bool minimized, bool occluded);
+
+    virtual bool is_visible_for_timer_purposes() const override { return m_visible_for_timer_purposes; }
+
+    Action* action_for_key_event(const KeyEvent&);
+
+    void did_add_widget(Badge<Widget>, Widget&);
+    void did_remove_widget(Badge<Widget>, Widget&);
+
+    Window* find_parent_window();
+
+    void set_progress(int);
+
+protected:
+    Window(Core::Object* parent = nullptr);
+    virtual void wm_event(WMEvent&);
+
+private:
+    virtual bool is_window() const override final { return true; }
+
+    void handle_drop_event(DropEvent&);
+    void handle_mouse_event(MouseEvent&);
+    void handle_multi_paint_event(MultiPaintEvent&);
+    void handle_key_event(KeyEvent&);
+    void handle_resize_event(ResizeEvent&);
+    void handle_input_entered_or_left_event(Core::Event&);
+    void handle_became_active_or_inactive_event(Core::Event&);
+    void handle_close_request();
+    void handle_theme_change_event(ThemeChangeEvent&);
+    void handle_drag_move_event(DragEvent&);
+    void handle_left_event();
+
+    void server_did_destroy();
+
+    RefPtr<Gfx::Bitmap> create_backing_bitmap(const Gfx::IntSize&);
+    RefPtr<Gfx::Bitmap> create_shared_bitmap(Gfx::BitmapFormat, const Gfx::IntSize&);
+    void set_current_backing_bitmap(Gfx::Bitmap&, bool flush_immediately = false);
+    void flip(const Vector<Gfx::IntRect, 32>& dirty_rects);
+    void force_update();
+
+    RefPtr<Gfx::Bitmap> m_front_bitmap;
+    RefPtr<Gfx::Bitmap> m_back_bitmap;
+    RefPtr<Gfx::Bitmap> m_icon;
+    RefPtr<Gfx::Bitmap> m_custom_cursor;
+    int m_window_id { 0 };
+    float m_opacity_when_windowless { 1.0f };
+    RefPtr<Widget> m_main_widget;
+    WeakPtr<Widget> m_focused_widget;
+    WeakPtr<Widget> m_global_cursor_tracking_widget;
+    WeakPtr<Widget> m_automatic_cursor_tracking_widget;
+    WeakPtr<Widget> m_hovered_widget;
+    Gfx::IntRect m_rect_when_windowless;
+    String m_title_when_windowless;
+    Vector<Gfx::IntRect, 32> m_pending_paint_event_rects;
+    Gfx::IntSize m_size_increment;
+    Gfx::IntSize m_base_size;
+    Color m_background_color { Color::WarmGray };
+    WindowType m_window_type { WindowType::Normal };
+    StandardCursor m_override_cursor { StandardCursor::None };
+    bool m_is_active { false };
+    bool m_is_active_input { false };
+    bool m_has_alpha_channel { false };
+    bool m_double_buffering_enabled { true };
+    bool m_modal { false };
+    bool m_resizable { true };
+    bool m_minimizable { true };
+    bool m_fullscreen { false };
+    bool m_frameless { false };
+    bool m_layout_pending { false };
+    bool m_visible_for_timer_purposes { true };
+    bool m_visible { false };
+    bool m_accessory { false };
+};
+
+}
+
+template<>
+inline bool Core::is<GUI::Window>(const Core::Object& object)
+{
+    return object.is_window();
+}