summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibGfx/ClassicWindowTheme.cpp22
-rw-r--r--Userland/Libraries/LibGfx/ClassicWindowTheme.h9
-rw-r--r--Userland/Libraries/LibGfx/Painter.cpp14
-rw-r--r--Userland/Libraries/LibGfx/WindowTheme.h1
-rw-r--r--Userland/Services/WindowServer/WindowFrame.cpp18
-rw-r--r--Userland/Services/WindowServer/WindowFrame.h11
6 files changed, 55 insertions, 20 deletions
diff --git a/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp b/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp
index 5476bec441..7b51828c68 100644
--- a/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp
+++ b/Userland/Libraries/LibGfx/ClassicWindowTheme.cpp
@@ -89,11 +89,13 @@ void ClassicWindowTheme::paint_normal_frame(Painter& painter, WindowState window
painter.fill_rect_with_gradient(titlebar_rect, border_color, border_color2);
- int stripe_left = titlebar_title_rect.right() + 5;
int stripe_right = leftmost_button_rect.left() - 3;
- if (stripe_left && stripe_right && stripe_left < stripe_right) {
- for (int i = 2; i <= titlebar_inner_rect.height() - 2; i += 2) {
- painter.draw_line({ stripe_left, titlebar_inner_rect.y() + i }, { stripe_right, titlebar_inner_rect.y() + i }, stripes_color);
+ if (stripes_color.alpha() > 0) {
+ int stripe_left = titlebar_title_rect.right() + 5;
+ if (stripe_left && stripe_right && stripe_left < stripe_right) {
+ for (int i = 2; i <= titlebar_inner_rect.height() - 2; i += 2) {
+ painter.draw_line({ stripe_left, titlebar_inner_rect.y() + i }, { stripe_right, titlebar_inner_rect.y() + i }, stripes_color);
+ }
}
}
@@ -145,11 +147,13 @@ void ClassicWindowTheme::paint_notification_frame(Painter& painter, const IntRec
auto titlebar_rect = title_bar_rect(WindowType::Notification, window_rect, palette);
painter.fill_rect_with_gradient(Gfx::Orientation::Vertical, titlebar_rect, palette.active_window_border1(), palette.active_window_border2());
- int stripe_top = close_button_rect.bottom() + 4;
- int stripe_bottom = window_rect.height() - 3;
- if (stripe_top && stripe_bottom && stripe_top < stripe_bottom) {
- for (int i = 2; i <= palette.window_title_height() - 2; i += 2) {
- painter.draw_line({ titlebar_rect.x() + i, stripe_top }, { titlebar_rect.x() + i, stripe_bottom }, palette.active_window_title_stripes());
+ if (palette.active_window_title_stripes().alpha() > 0) {
+ int stripe_top = close_button_rect.bottom() + 4;
+ int stripe_bottom = window_rect.height() - 3;
+ if (stripe_top && stripe_bottom && stripe_top < stripe_bottom) {
+ for (int i = 2; i <= palette.window_title_height() - 2; i += 2) {
+ painter.draw_line({ titlebar_rect.x() + i, stripe_top }, { titlebar_rect.x() + i, stripe_bottom }, palette.active_window_title_stripes());
+ }
}
}
}
diff --git a/Userland/Libraries/LibGfx/ClassicWindowTheme.h b/Userland/Libraries/LibGfx/ClassicWindowTheme.h
index c1d53fd492..165997bfa4 100644
--- a/Userland/Libraries/LibGfx/ClassicWindowTheme.h
+++ b/Userland/Libraries/LibGfx/ClassicWindowTheme.h
@@ -48,6 +48,10 @@ public:
virtual Vector<IntRect> layout_buttons(WindowType, const IntRect& window_rect, const Palette&, size_t buttons) const override;
virtual bool is_simple_rect_frame() const override { return true; }
+ virtual bool frame_uses_alpha(WindowState state, const Palette& palette) const override
+ {
+ return compute_frame_colors(state, palette).uses_alpha();
+ }
private:
struct FrameColors {
@@ -56,6 +60,11 @@ private:
Color border_color2;
Color title_stripes_color;
Color title_shadow_color;
+
+ bool uses_alpha() const
+ {
+ return title_color.alpha() != 0xff || border_color.alpha() != 0xff || border_color2.alpha() != 0xff || title_stripes_color.alpha() != 0xff || title_shadow_color.alpha() != 0xff;
+ }
};
FrameColors compute_frame_colors(WindowState, const Palette&) const;
diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp
index 3ff25202d3..f1d96e8e21 100644
--- a/Userland/Libraries/LibGfx/Painter.cpp
+++ b/Userland/Libraries/LibGfx/Painter.cpp
@@ -206,6 +206,10 @@ void Painter::fill_rect_with_checkerboard(const IntRect& a_rect, const IntSize&
void Painter::fill_rect_with_gradient(Orientation orientation, const IntRect& a_rect, Color gradient_start, Color gradient_end)
{
+ if (gradient_start == gradient_end) {
+ fill_rect(a_rect, gradient_start);
+ return;
+ }
#ifdef NO_FPU
return fill_rect(a_rect, gradient_start);
@@ -222,23 +226,31 @@ void Painter::fill_rect_with_gradient(Orientation orientation, const IntRect& a_
const size_t dst_skip = m_target->pitch() / sizeof(RGBA32);
float increment = (1.0 / ((rect.primary_size_for_orientation(orientation))));
+ float alpha_increment = increment * ((float)gradient_end.alpha() - (float)gradient_start.alpha());
if (orientation == Orientation::Horizontal) {
for (int i = clipped_rect.height() - 1; i >= 0; --i) {
float c = offset * increment;
+ float c_alpha = gradient_start.alpha() + offset * alpha_increment;
for (int j = 0; j < clipped_rect.width(); ++j) {
- dst[j] = gamma_accurate_blend(gradient_start, gradient_end, c).value();
+ auto color = gamma_accurate_blend(gradient_start, gradient_end, c);
+ color.set_alpha(c_alpha);
+ dst[j] = color.value();
+ c_alpha += alpha_increment;
c += increment;
}
dst += dst_skip;
}
} else {
float c = offset * increment;
+ float c_alpha = gradient_start.alpha() + offset * alpha_increment;
for (int i = clipped_rect.height() - 1; i >= 0; --i) {
auto color = gamma_accurate_blend(gradient_start, gradient_end, c);
+ color.set_alpha(c_alpha);
for (int j = 0; j < clipped_rect.width(); ++j) {
dst[j] = color.value();
}
+ c_alpha += alpha_increment;
c += increment;
dst += dst_skip;
}
diff --git a/Userland/Libraries/LibGfx/WindowTheme.h b/Userland/Libraries/LibGfx/WindowTheme.h
index 73c0045458..383eadcca3 100644
--- a/Userland/Libraries/LibGfx/WindowTheme.h
+++ b/Userland/Libraries/LibGfx/WindowTheme.h
@@ -62,6 +62,7 @@ public:
virtual Vector<IntRect> layout_buttons(WindowType, const IntRect& window_rect, const Palette&, size_t buttons) const = 0;
virtual bool is_simple_rect_frame() const = 0;
+ virtual bool frame_uses_alpha(WindowState, const Palette&) const = 0;
protected:
WindowTheme() { }
diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp
index 9c17e967d9..349ab999a3 100644
--- a/Userland/Services/WindowServer/WindowFrame.cpp
+++ b/Userland/Services/WindowServer/WindowFrame.cpp
@@ -221,6 +221,8 @@ Gfx::Bitmap* WindowFrame::window_shadow() const
bool WindowFrame::frame_has_alpha() const
{
+ if (m_has_alpha_channel)
+ return true;
if (auto* shadow_bitmap = window_shadow(); shadow_bitmap && shadow_bitmap->format() == Gfx::BitmapFormat::RGBA32)
return true;
return false;
@@ -347,12 +349,27 @@ void WindowFrame::render(Gfx::Painter& painter)
}
}
+void WindowFrame::theme_changed()
+{
+ m_dirty = m_shadow_dirty = true;
+ m_top_bottom = nullptr;
+ m_left_right = nullptr;
+ m_bottom_y = m_right_x = 0;
+
+ layout_buttons();
+ set_button_icons();
+
+ m_has_alpha_channel = Gfx::WindowTheme::current().frame_uses_alpha(window_state_for_theme(), WindowManager::the().palette());
+}
+
void WindowFrame::render_to_cache()
{
if (!m_dirty)
return;
m_dirty = false;
+ m_has_alpha_channel = Gfx::WindowTheme::current().frame_uses_alpha(window_state_for_theme(), WindowManager::the().palette());
+
static Gfx::Bitmap* s_tmp_bitmap;
auto frame_rect = rect();
auto total_frame_rect = frame_rect;
@@ -387,6 +404,7 @@ void WindowFrame::render_to_cache()
Gfx::IntPoint update_location(m_shadow_dirty ? Gfx::IntPoint { 0, 0 } : m_shadow_offset);
Gfx::Painter painter(*s_tmp_bitmap);
+
// Clear the frame area, not including the window content area, which we don't care about
for (auto& rect : frame_rect_to_update.shatter(window_rect))
painter.clear_rect({ rect.location() - frame_rect_to_update.location(), rect.size() }, { 255, 255, 255, 0 });
diff --git a/Userland/Services/WindowServer/WindowFrame.h b/Userland/Services/WindowServer/WindowFrame.h
index 992ce11921..872597f29a 100644
--- a/Userland/Services/WindowServer/WindowFrame.h
+++ b/Userland/Services/WindowServer/WindowFrame.h
@@ -88,16 +88,7 @@ public:
m_shadow_dirty |= re_render_shadow;
}
- void theme_changed()
- {
- m_dirty = m_shadow_dirty = true;
- m_top_bottom = nullptr;
- m_left_right = nullptr;
- m_bottom_y = m_right_x = 0;
-
- layout_buttons();
- set_button_icons();
- }
+ void theme_changed();
private:
void paint_simple_rect_shadow(Gfx::Painter&, const Gfx::IntRect&, const Gfx::Bitmap&) const;