summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-02-21 00:21:23 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-02-21 00:21:23 +0100
commit6084cd0c56f9d1949b8bb07db5729d2a0108d5a4 (patch)
tree63aa1fb2ff50cc5c132c6be67b671e316ca05bf2
parentfd575055c2215ce2ce42efaa82be53a94c7b3932 (diff)
downloadserenity-6084cd0c56f9d1949b8bb07db5729d2a0108d5a4.zip
Add concept of size increments to windowing system.
Use this to implement incremental resizing for Terminal so that we only ever resize to fit a perfect number of rows and columns. This is very nice. :^)
-rw-r--r--Applications/Terminal/Terminal.cpp7
-rw-r--r--Applications/Terminal/Terminal.h2
-rw-r--r--Applications/Terminal/main.cpp1
-rw-r--r--LibGUI/GWindow.cpp2
-rw-r--r--LibGUI/GWindow.h7
-rw-r--r--SharedGraphics/Size.h3
-rw-r--r--WindowServer/WSAPITypes.h2
-rw-r--r--WindowServer/WSClientConnection.cpp1
-rw-r--r--WindowServer/WSMessage.h8
-rw-r--r--WindowServer/WSMessageLoop.cpp2
-rw-r--r--WindowServer/WSWindow.h8
-rw-r--r--WindowServer/WSWindowManager.cpp8
12 files changed, 47 insertions, 4 deletions
diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp
index 9407fdba06..76b753af35 100644
--- a/Applications/Terminal/Terminal.cpp
+++ b/Applications/Terminal/Terminal.cpp
@@ -785,7 +785,6 @@ void Terminal::force_repaint()
{
for (int i = 0; i < m_rows; ++i)
line(i).dirty = true;
- m_need_full_flush = true;
update();
}
@@ -795,3 +794,9 @@ void Terminal::resize_event(GResizeEvent& event)
int new_rows = event.size().height() / m_line_height;
set_size(new_columns, new_rows);
}
+
+void Terminal::apply_size_increments_to_window(GWindow& window)
+{
+ window.set_size_increment({ font().glyph_width(), m_line_height });
+ window.set_base_size({ m_inset, m_inset });
+}
diff --git a/Applications/Terminal/Terminal.h b/Applications/Terminal/Terminal.h
index e2b622cd20..67e453bc5a 100644
--- a/Applications/Terminal/Terminal.h
+++ b/Applications/Terminal/Terminal.h
@@ -21,6 +21,8 @@ public:
void flush_dirty_lines();
void force_repaint();
+ void apply_size_increments_to_window(GWindow&);
+
private:
virtual void event(GEvent&) override;
virtual void paint_event(GPaintEvent&) override;
diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp
index a63970a7ee..94ec08829c 100644
--- a/Applications/Terminal/main.cpp
+++ b/Applications/Terminal/main.cpp
@@ -92,6 +92,7 @@ int main(int argc, char** argv)
window->set_has_alpha_channel(true);
window->set_main_widget(&terminal);
window->move_to(300, 300);
+ terminal.apply_size_increments_to_window(*window);
window->show();
auto menubar = make<GMenuBar>();
diff --git a/LibGUI/GWindow.cpp b/LibGUI/GWindow.cpp
index f7b9bf000e..75bfc71ccb 100644
--- a/LibGUI/GWindow.cpp
+++ b/LibGUI/GWindow.cpp
@@ -61,6 +61,8 @@ void GWindow::show()
request.window.rect = m_rect_when_windowless;
request.window.has_alpha_channel = m_has_alpha_channel;
request.window.opacity = m_opacity_when_windowless;
+ request.window.size_increment = m_size_increment;
+ request.window.base_size = m_base_size;
ASSERT(m_title_when_windowless.length() < sizeof(request.text));
strcpy(request.text, m_title_when_windowless.characters());
request.text_length = m_title_when_windowless.length();
diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h
index c40387cf7c..21328d224c 100644
--- a/LibGUI/GWindow.h
+++ b/LibGUI/GWindow.h
@@ -70,6 +70,11 @@ public:
GraphicsBitmap* backing() { return m_backing.ptr(); }
+ Size size_increment() const { return m_size_increment; }
+ void set_size_increment(const Size& increment) { m_size_increment = increment; }
+ Size base_size() const { return m_base_size; }
+ void set_base_size(const Size& size) { m_base_size = size; }
+
private:
virtual const char* class_name() const override { return "GWindow"; }
@@ -83,6 +88,8 @@ private:
Rect m_rect_when_windowless;
String m_title_when_windowless;
Vector<Rect> m_pending_paint_event_rects;
+ Size m_size_increment;
+ Size m_base_size;
bool m_is_active { false };
bool m_should_exit_app_on_close { false };
bool m_has_alpha_channel { false };
diff --git a/SharedGraphics/Size.h b/SharedGraphics/Size.h
index d5d914af19..62cf8b1c4b 100644
--- a/SharedGraphics/Size.h
+++ b/SharedGraphics/Size.h
@@ -10,7 +10,8 @@ public:
Size(int w, int h) : m_width(w), m_height(h) { }
Size(const WSAPI_Size&);
- bool is_empty() const { return !m_width || !m_height; }
+ bool is_null() const { return !m_width && !m_height; }
+ bool is_empty() const { return m_width <= 0 || m_height <= 0; }
int width() const { return m_width; }
int height() const { return m_height; }
diff --git a/WindowServer/WSAPITypes.h b/WindowServer/WSAPITypes.h
index da39a9a04e..9cd0fea2d8 100644
--- a/WindowServer/WSAPITypes.h
+++ b/WindowServer/WSAPITypes.h
@@ -170,6 +170,8 @@ struct WSAPI_ClientMessage {
WSAPI_Rect rect;
bool has_alpha_channel;
float opacity;
+ WSAPI_Size base_size;
+ WSAPI_Size size_increment;
} window;
struct {
WSAPI_Size size;
diff --git a/WindowServer/WSClientConnection.cpp b/WindowServer/WSClientConnection.cpp
index 2a171a8056..b3c1271424 100644
--- a/WindowServer/WSClientConnection.cpp
+++ b/WindowServer/WSClientConnection.cpp
@@ -319,6 +319,7 @@ void WSClientConnection::handle_request(WSAPICreateWindowRequest& request)
window->set_title(request.title());
window->set_rect(request.rect());
window->set_opacity(request.opacity());
+ window->set_size_increment(request.size_increment());
m_windows.set(window_id, move(window));
WSAPI_ServerMessage response;
response.type = WSAPI_ServerMessage::Type::DidCreateWindow;
diff --git a/WindowServer/WSMessage.h b/WindowServer/WSMessage.h
index b87b0339cb..cf7a8bc319 100644
--- a/WindowServer/WSMessage.h
+++ b/WindowServer/WSMessage.h
@@ -349,12 +349,14 @@ private:
class WSAPICreateWindowRequest : public WSAPIClientRequest {
public:
- WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, float opacity)
+ WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, float opacity, const Size& base_size, const Size& size_increment)
: WSAPIClientRequest(WSMessage::APICreateWindowRequest, client_id)
, m_rect(rect)
, m_title(title)
, m_opacity(opacity)
, m_has_alpha_channel(has_alpha_channel)
+ , m_base_size(base_size)
+ , m_size_increment(size_increment)
{
}
@@ -362,12 +364,16 @@ public:
String title() const { return m_title; }
bool has_alpha_channel() const { return m_has_alpha_channel; }
float opacity() const { return m_opacity; }
+ Size size_increment() const { return m_size_increment; }
+ Size base_size() const { return m_base_size; }
private:
Rect m_rect;
String m_title;
float m_opacity { 0 };
bool m_has_alpha_channel { false };
+ Size m_size_increment;
+ Size m_base_size;
};
class WSAPIDestroyWindowRequest : public WSAPIClientRequest {
diff --git a/WindowServer/WSMessageLoop.cpp b/WindowServer/WSMessageLoop.cpp
index bbdec4fe35..15ea696fc6 100644
--- a/WindowServer/WSMessageLoop.cpp
+++ b/WindowServer/WSMessageLoop.cpp
@@ -302,7 +302,7 @@ void WSMessageLoop::on_receive_from_client(int client_id, const WSAPI_ClientMess
break;
case WSAPI_ClientMessage::Type::CreateWindow:
ASSERT(message.text_length < sizeof(message.text));
- post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.opacity));
+ post_message(client, make<WSAPICreateWindowRequest>(client_id, message.window.rect, String(message.text, message.text_length), message.window.has_alpha_channel, message.window.opacity, message.window.base_size, message.window.size_increment));
break;
case WSAPI_ClientMessage::Type::DestroyWindow:
post_message(client, make<WSAPIDestroyWindowRequest>(client_id, message.window_id));
diff --git a/WindowServer/WSWindow.h b/WindowServer/WSWindow.h
index f4d6c28b5d..15745a55a0 100644
--- a/WindowServer/WSWindow.h
+++ b/WindowServer/WSWindow.h
@@ -70,6 +70,12 @@ public:
bool has_painted_since_last_resize() const { return m_has_painted_since_last_resize; }
void set_has_painted_since_last_resize(bool b) { m_has_painted_since_last_resize = b; }
+ Size size_increment() const { return m_size_increment; }
+ void set_size_increment(const Size& increment) { m_size_increment = increment; }
+
+ Size base_size() const { return m_base_size; }
+ void set_base_size(const Size& size) { m_base_size = size; }
+
// For InlineLinkedList.
// FIXME: Maybe make a ListHashSet and then WSWindowManager can just use that.
WSWindow* m_next { nullptr };
@@ -89,4 +95,6 @@ private:
int m_window_id { -1 };
float m_opacity { 1 };
Rect m_last_lazy_resize_rect;
+ Size m_size_increment;
+ Size m_base_size;
};
diff --git a/WindowServer/WSWindowManager.cpp b/WindowServer/WSWindowManager.cpp
index 6f30461a28..1b7640cb69 100644
--- a/WindowServer/WSWindowManager.cpp
+++ b/WindowServer/WSWindowManager.cpp
@@ -548,6 +548,14 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& event_
auto new_rect = m_resize_window_original_rect;
new_rect.set_width(max(50, new_rect.width() + dx));
new_rect.set_height(max(50, new_rect.height() + dy));
+
+ if (!m_resize_window->size_increment().is_null()) {
+ int horizontal_incs = (new_rect.width() - m_resize_window->base_size().width()) / m_resize_window->size_increment().width();
+ new_rect.set_width(m_resize_window->base_size().width() + horizontal_incs * m_resize_window->size_increment().width());
+ int vertical_incs = (new_rect.height() - m_resize_window->base_size().height()) / m_resize_window->size_increment().height();
+ new_rect.set_height(m_resize_window->base_size().height() + vertical_incs * m_resize_window->size_increment().height());
+ }
+
if (m_resize_window->rect() == new_rect)
return;
#ifdef RESIZE_DEBUG