зеркало из https://github.com/mozilla/gecko-dev.git
Fixing the painting of the overlap area between tabs. Not part of the build.
This commit is contained in:
Родитель
d223897858
Коммит
bbdbac2222
|
@ -413,22 +413,53 @@ moz_gtk_progress_chunk_paint(GdkWindow* window, GtkStyle* style,
|
|||
|
||||
void
|
||||
moz_gtk_tab_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkTabType type)
|
||||
GdkRectangle* cliprect, gint flags)
|
||||
{
|
||||
/*
|
||||
* In order to get the correct shadows and highlights, GTK paints tabs
|
||||
* right-to-left (end-to-beginning, to be generic), leaving out the
|
||||
* active tab, and then paints the current tab once everything else is
|
||||
* painted. In addition, GTK uses a 2-pixel overlap between adjacent tabs
|
||||
* (this value is hard-coded in gtknotebook.c). For purposes of mapping to
|
||||
* gecko's frame positions, we put this overlap on the far edge of the frame
|
||||
* (i.e., for a horizontal/top tab strip, we shift the left side of each tab
|
||||
* 2px to the left, into the neighboring tab's frame rect. The right 2px
|
||||
* of a tab's frame will be referred to as the "overlap area".
|
||||
*
|
||||
* Since we can't guarantee painting order with gecko, we need to manage
|
||||
* the overlap area manually. There are three types of tab boundaries we need to handle:
|
||||
*
|
||||
* * two non-active tabs: In this case, we just have both tabs paint normally.
|
||||
*
|
||||
* * non-active to active tab: Here, we need the tab on the left to paint itself
|
||||
* normally, then paint the edge of the active tab
|
||||
* in its overlap area.
|
||||
*
|
||||
* * active to non-active tab: In this case, we just have both tabs paint normally.
|
||||
*
|
||||
* We need to make an exception for the first tab - since there is no tab to the
|
||||
* left to paint the overlap area, we do _not_ shift the tab left by 2px.
|
||||
*/
|
||||
|
||||
if (!(flags & MOZ_GTK_TAB_FIRST)) {
|
||||
rect->x -= 2;
|
||||
rect->width += 2;
|
||||
}
|
||||
|
||||
gtk_paint_extension(style, window,
|
||||
(type == kTabSelected ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE),
|
||||
((flags & MOZ_GTK_TAB_SELECTED) ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE),
|
||||
GTK_SHADOW_OUT, cliprect, gTabWidget, "tab", rect->x,
|
||||
rect->y, rect->width, rect->height, GTK_POS_BOTTOM);
|
||||
|
||||
/* Here is the sleazy hack for before/after selected tab */
|
||||
if (type == kTabBeforeSelected)
|
||||
gtk_paint_extension(style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
|
||||
cliprect, gTabWidget, "tab", rect->x + rect->width,
|
||||
rect->y, rect->width, rect->height, GTK_POS_BOTTOM);
|
||||
else if (type == kTabAfterSelected)
|
||||
gtk_paint_extension(style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
|
||||
cliprect, gTabWidget, "tab", rect->x - rect->width,
|
||||
rect->y, rect->width, rect->height, GTK_POS_BOTTOM);
|
||||
if (flags & MOZ_GTK_TAB_BEFORE_SELECTED) {
|
||||
gboolean before_selected = ((flags & MOZ_GTK_TAB_BEFORE_SELECTED) != 0);
|
||||
cliprect->y -= 2;
|
||||
cliprect->height += 2;
|
||||
gtk_paint_extension(style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, cliprect,
|
||||
gTabWidget, "tab", rect->x + rect->width - 2,
|
||||
rect->y - (2 * before_selected), rect->width,
|
||||
rect->height + (2 * before_selected), GTK_POS_BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -56,12 +56,10 @@ typedef struct {
|
|||
PRPackedBool canDefault;
|
||||
} GtkWidgetState;
|
||||
|
||||
typedef enum {
|
||||
kTabNormal,
|
||||
kTabBeforeSelected,
|
||||
kTabSelected,
|
||||
kTabAfterSelected
|
||||
} GtkTabType;
|
||||
/* flags for tab state */
|
||||
#define MOZ_GTK_TAB_FIRST (1<<0)
|
||||
#define MOZ_GTK_TAB_BEFORE_SELECTED (1<<1)
|
||||
#define MOZ_GTK_TAB_SELECTED (1<<2)
|
||||
|
||||
void
|
||||
moz_gtk_button_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
|
||||
|
@ -132,7 +130,7 @@ moz_gtk_progress_chunk_paint(GdkWindow* window, GtkStyle* style,
|
|||
|
||||
void
|
||||
moz_gtk_tab_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* rect,
|
||||
GdkRectangle* cliprect, GtkTabType type);
|
||||
GdkRectangle* cliprect, gint flags);
|
||||
|
||||
void
|
||||
moz_gtk_tabpanels_paint(GdkWindow* window, GtkStyle* style,
|
||||
|
|
|
@ -80,6 +80,7 @@ nsNativeThemeGTK::nsNativeThemeGTK()
|
|||
mInputCheckedAtom = do_GetAtom("_moz-input-checked");
|
||||
mInputAtom = do_GetAtom("input");
|
||||
mFocusedAtom = do_GetAtom("focused");
|
||||
mFirstTabAtom = do_GetAtom("first-tab");
|
||||
}
|
||||
|
||||
nsNativeThemeGTK::~nsNativeThemeGTK() {
|
||||
|
@ -364,24 +365,20 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext,
|
|||
case NS_THEME_TAB_RIGHT_EDGE:
|
||||
{
|
||||
EnsureTabWidget();
|
||||
GtkTabType tab_type;
|
||||
switch (aWidgetType) {
|
||||
case NS_THEME_TAB:
|
||||
{
|
||||
PRBool isSelected = CheckBooleanAttr(aFrame, mSelectedAtom);
|
||||
tab_type = (isSelected ? kTabSelected : kTabNormal);
|
||||
}
|
||||
break;
|
||||
case NS_THEME_TAB_LEFT_EDGE:
|
||||
tab_type = kTabBeforeSelected;
|
||||
break;
|
||||
case NS_THEME_TAB_RIGHT_EDGE:
|
||||
tab_type = kTabAfterSelected;
|
||||
break;
|
||||
}
|
||||
gint tab_flags = 0;
|
||||
|
||||
if (aWidgetType == NS_THEME_TAB && CheckBooleanAttr(aFrame, mSelectedAtom))
|
||||
tab_flags |= MOZ_GTK_TAB_SELECTED;
|
||||
else if (aWidgetType == NS_THEME_TAB_LEFT_EDGE)
|
||||
tab_flags |= MOZ_GTK_TAB_BEFORE_SELECTED;
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
aFrame->GetContent(getter_AddRefs(content));
|
||||
if (content->HasAttr(kNameSpaceID_None, mFirstTabAtom))
|
||||
tab_flags |= MOZ_GTK_TAB_FIRST;
|
||||
|
||||
moz_gtk_tab_paint(window, gTabWidget->style, &gdk_rect, &gdk_clip,
|
||||
tab_type);
|
||||
tab_flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,7 @@ private:
|
|||
nsCOMPtr<nsIAtom> mInputCheckedAtom;
|
||||
nsCOMPtr<nsIAtom> mInputAtom;
|
||||
nsCOMPtr<nsIAtom> mFocusedAtom;
|
||||
nsCOMPtr<nsIAtom> mFirstTabAtom;
|
||||
|
||||
GtkWidget* mProtoLayout;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче