зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1432090 - Honor GTK button layout. r=stransky,desktop-theme-reviewers,dao
This is based off work by smurfd. But this patch doesn't support buttons both at the left and right, which simplifies a lot the implementation. Also, clean-up the existing env variables while at it. Co-authored-by: Nicklas Boman <smurfd@gmail.com> Differential Revision: https://phabricator.services.mozilla.com/D132073
This commit is contained in:
Родитель
6a0cba6df9
Коммит
4354146592
|
@ -397,18 +397,22 @@ menuitem.bookmark-item {
|
|||
.titlebar-min {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: -moz-window-button-minimize;
|
||||
-moz-box-ordinal-group: env(-moz-gtk-csd-minimize-button-position);
|
||||
}
|
||||
.titlebar-max {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: -moz-window-button-maximize;
|
||||
-moz-box-ordinal-group: env(-moz-gtk-csd-maximize-button-position);
|
||||
}
|
||||
.titlebar-restore {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: -moz-window-button-restore;
|
||||
-moz-box-ordinal-group: env(-moz-gtk-csd-maximize-button-position);
|
||||
}
|
||||
.titlebar-close {
|
||||
appearance: auto;
|
||||
-moz-default-appearance: -moz-window-button-close;
|
||||
-moz-box-ordinal-group: env(-moz-gtk-csd-close-button-position);
|
||||
}
|
||||
|
||||
/* When using lightweight themes, use our own buttons since native ones might
|
||||
|
@ -466,8 +470,7 @@ menuitem.bookmark-item {
|
|||
}
|
||||
|
||||
@media (-moz-gtk-csd-reversed-placement) {
|
||||
.titlebar-buttonbox-container,
|
||||
.titlebar-close {
|
||||
.titlebar-buttonbox-container {
|
||||
-moz-box-ordinal-group: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
<script>
|
||||
const NON_CONTENT_ACCESSIBLE_ENV_VARS = [
|
||||
"-moz-gtk-csd-titlebar-radius",
|
||||
"-moz-gtk-csd-menu-radius",
|
||||
"-moz-gtk-csd-minimize-button-position",
|
||||
"-moz-gtk-csd-maximize-button-position",
|
||||
"-moz-gtk-csd-close-button-position",
|
||||
];
|
||||
|
||||
const div = document.querySelector("div");
|
||||
|
|
|
@ -49,19 +49,19 @@ macro_rules! make_variable {
|
|||
}
|
||||
|
||||
fn get_safearea_inset_top(device: &Device) -> VariableValue {
|
||||
VariableValue::pixel(device.safe_area_insets().top)
|
||||
VariableValue::pixels(device.safe_area_insets().top)
|
||||
}
|
||||
|
||||
fn get_safearea_inset_bottom(device: &Device) -> VariableValue {
|
||||
VariableValue::pixel(device.safe_area_insets().bottom)
|
||||
VariableValue::pixels(device.safe_area_insets().bottom)
|
||||
}
|
||||
|
||||
fn get_safearea_inset_left(device: &Device) -> VariableValue {
|
||||
VariableValue::pixel(device.safe_area_insets().left)
|
||||
VariableValue::pixels(device.safe_area_insets().left)
|
||||
}
|
||||
|
||||
fn get_safearea_inset_right(device: &Device) -> VariableValue {
|
||||
VariableValue::pixel(device.safe_area_insets().right)
|
||||
VariableValue::pixels(device.safe_area_insets().right)
|
||||
}
|
||||
|
||||
static ENVIRONMENT_VARIABLES: [EnvironmentVariable; 4] = [
|
||||
|
@ -71,17 +71,47 @@ static ENVIRONMENT_VARIABLES: [EnvironmentVariable; 4] = [
|
|||
make_variable!(atom!("safe-area-inset-right"), get_safearea_inset_right),
|
||||
];
|
||||
|
||||
fn get_titlebar_radius(device: &Device) -> VariableValue {
|
||||
VariableValue::pixel(device.titlebar_radius())
|
||||
macro_rules! lnf_int {
|
||||
($id:ident) => {
|
||||
unsafe {
|
||||
crate::gecko_bindings::bindings::Gecko_GetLookAndFeelInt(
|
||||
crate::gecko_bindings::bindings::LookAndFeel_IntID::$id as i32,
|
||||
)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn get_menu_radius(device: &Device) -> VariableValue {
|
||||
VariableValue::pixel(device.menu_radius())
|
||||
macro_rules! lnf_int_variable {
|
||||
($atom:expr, $id:ident, $ctor:ident) => {{
|
||||
fn __eval(_: &Device) -> VariableValue {
|
||||
VariableValue::$ctor(lnf_int!($id))
|
||||
}
|
||||
make_variable!($atom, __eval)
|
||||
}};
|
||||
}
|
||||
|
||||
static CHROME_ENVIRONMENT_VARIABLES: [EnvironmentVariable; 2] = [
|
||||
make_variable!(atom!("-moz-gtk-csd-titlebar-radius"), get_titlebar_radius),
|
||||
make_variable!(atom!("-moz-gtk-menu-radius"), get_menu_radius),
|
||||
static CHROME_ENVIRONMENT_VARIABLES: [EnvironmentVariable; 5] = [
|
||||
lnf_int_variable!(
|
||||
atom!("-moz-gtk-csd-titlebar-radius"),
|
||||
TitlebarRadius,
|
||||
int_pixels
|
||||
),
|
||||
lnf_int_variable!(atom!("-moz-gtk-csd-menu-radius"), GtkMenuRadius, int_pixels),
|
||||
lnf_int_variable!(
|
||||
atom!("-moz-gtk-csd-close-button-position"),
|
||||
GTKCSDCloseButtonPosition,
|
||||
integer
|
||||
),
|
||||
lnf_int_variable!(
|
||||
atom!("-moz-gtk-csd-minimize-button-position"),
|
||||
GTKCSDMinimizeButtonPosition,
|
||||
integer
|
||||
),
|
||||
lnf_int_variable!(
|
||||
atom!("-moz-gtk-csd-maximize-button-position"),
|
||||
GTKCSDMaximizeButtonPosition,
|
||||
integer
|
||||
),
|
||||
];
|
||||
|
||||
impl CssEnvironment {
|
||||
|
@ -280,17 +310,39 @@ impl VariableValue {
|
|||
}))
|
||||
}
|
||||
|
||||
/// Create VariableValue from css pixel value
|
||||
pub fn pixel(number: f32) -> Self {
|
||||
/// Create VariableValue from an int.
|
||||
fn integer(number: i32) -> Self {
|
||||
Self::from_token(Token::Number {
|
||||
has_sign: false,
|
||||
value: number as f32,
|
||||
int_value: Some(number),
|
||||
})
|
||||
}
|
||||
|
||||
/// Create VariableValue from a float amount of CSS pixels.
|
||||
fn pixels(number: f32) -> Self {
|
||||
// FIXME (https://github.com/servo/rust-cssparser/issues/266):
|
||||
// No way to get TokenSerializationType::Dimension without creating
|
||||
// Token object.
|
||||
let token = Token::Dimension {
|
||||
Self::from_token(Token::Dimension {
|
||||
has_sign: false,
|
||||
value: number,
|
||||
int_value: None,
|
||||
unit: CowRcStr::from("px"),
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
/// Create VariableValue from an integer amount of CSS pixels.
|
||||
fn int_pixels(number: i32) -> Self {
|
||||
Self::from_token(Token::Dimension {
|
||||
has_sign: false,
|
||||
value: number as f32,
|
||||
int_value: Some(number),
|
||||
unit: CowRcStr::from("px"),
|
||||
})
|
||||
}
|
||||
|
||||
fn from_token(token: Token) -> Self {
|
||||
let token_type = token.serialization_type();
|
||||
let mut css = token.to_css_string();
|
||||
css.shrink_to_fit();
|
||||
|
|
|
@ -387,22 +387,6 @@ impl Device {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the gtk titlebar radius in CSS pixels.
|
||||
pub fn titlebar_radius(&self) -> f32 {
|
||||
unsafe {
|
||||
bindings::Gecko_GetLookAndFeelInt(bindings::LookAndFeel_IntID::TitlebarRadius as i32)
|
||||
as f32
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the gtk menu radius in CSS pixels.
|
||||
pub fn menu_radius(&self) -> f32 {
|
||||
unsafe {
|
||||
bindings::Gecko_GetLookAndFeelInt(bindings::LookAndFeel_IntID::GtkMenuRadius as i32)
|
||||
as f32
|
||||
}
|
||||
}
|
||||
|
||||
/// Return whether the document is a chrome document.
|
||||
#[inline]
|
||||
pub fn is_chrome_document(&self) -> bool {
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
menupopup,
|
||||
panel {
|
||||
min-width: 1px;
|
||||
--panel-padding: max(env(-moz-gtk-menu-radius) - 1px, 0px) 0;
|
||||
--panel-padding: max(env(-moz-gtk-csd-menu-radius) - 1px, 0px) 0;
|
||||
--panel-color: MenuText;
|
||||
--panel-background: Menu;
|
||||
--panel-border-radius: env(-moz-gtk-menu-radius);
|
||||
--panel-border-radius: env(-moz-gtk-csd-menu-radius);
|
||||
--panel-border-color: ThreeDShadow;
|
||||
--panel-width: initial;
|
||||
/* To account for the box-shadow below */
|
||||
|
|
|
@ -264,25 +264,19 @@ class LookAndFeel {
|
|||
|
||||
/**
|
||||
* An Integer value that will represent the position of the Minimize button
|
||||
* in GTK Client side decoration header. Its value will be between 0 and 2
|
||||
* if it is on the left side of the tabbar, otherwise it will be between
|
||||
* 3 and 5.
|
||||
* in GTK Client side decoration header.
|
||||
*/
|
||||
GTKCSDMinimizeButtonPosition,
|
||||
|
||||
/**
|
||||
* An Integer value that will represent the position of the Maximize button
|
||||
* in GTK Client side decoration header. Its value will be between 0 and 2
|
||||
* if it is on the left side of the tabbar, otherwise it will be between
|
||||
* 3 and 5.
|
||||
* in GTK Client side decoration header.
|
||||
*/
|
||||
GTKCSDMaximizeButtonPosition,
|
||||
|
||||
/**
|
||||
* An Integer value that will represent the position of the Close button
|
||||
* in GTK Client side decoration header. Its value will be between 0 and 2
|
||||
* if it is on the left side of the tabbar, otherwise it will be between
|
||||
* 3 and 5.
|
||||
* in GTK Client side decoration header.
|
||||
*/
|
||||
GTKCSDCloseButtonPosition,
|
||||
|
||||
|
|
|
@ -426,30 +426,25 @@ size_t GetGtkHeaderBarButtonLayout(Span<ButtonLayout> aButtonLayout,
|
|||
|
||||
nsDependentCSubstring layout(decorationLayout, strlen(decorationLayout));
|
||||
|
||||
bool right = false;
|
||||
size_t activeButtons = 0;
|
||||
for (const auto& part : layout.Split(':')) {
|
||||
for (const auto& button : part.Split(',')) {
|
||||
if (button.EqualsLiteral("close")) {
|
||||
aButtonLayout[activeButtons++] = {MOZ_GTK_HEADER_BAR_BUTTON_CLOSE,
|
||||
right};
|
||||
aButtonLayout[activeButtons++] = {MOZ_GTK_HEADER_BAR_BUTTON_CLOSE};
|
||||
} else if (button.EqualsLiteral("minimize")) {
|
||||
aButtonLayout[activeButtons++] = {MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE,
|
||||
right};
|
||||
aButtonLayout[activeButtons++] = {MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE};
|
||||
} else if (button.EqualsLiteral("maximize")) {
|
||||
aButtonLayout[activeButtons++] = {MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE,
|
||||
right};
|
||||
aButtonLayout[activeButtons++] = {MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE};
|
||||
}
|
||||
if (activeButtons == aButtonLayout.Length()) {
|
||||
return activeButtons;
|
||||
}
|
||||
}
|
||||
right = true;
|
||||
}
|
||||
return activeButtons;
|
||||
}
|
||||
|
||||
static void EnsureToolbarMetrics(void) {
|
||||
static void EnsureToolbarMetrics() {
|
||||
if (!sToolbarMetrics.initialized) {
|
||||
// Make sure we have clean cache after theme reset, etc.
|
||||
memset(&sToolbarMetrics, 0, sizeof(sToolbarMetrics));
|
||||
|
@ -457,7 +452,7 @@ static void EnsureToolbarMetrics(void) {
|
|||
// Calculate titlebar button visibility and positions.
|
||||
ButtonLayout aButtonLayout[TOOLBAR_BUTTONS];
|
||||
size_t activeButtonNums =
|
||||
GetGtkHeaderBarButtonLayout(mozilla::Span(aButtonLayout), nullptr);
|
||||
GetGtkHeaderBarButtonLayout(Span(aButtonLayout), nullptr);
|
||||
|
||||
for (size_t i = 0; i < activeButtonNums; i++) {
|
||||
int buttonIndex =
|
||||
|
|
|
@ -356,7 +356,6 @@ enum WidgetNodeType : int {
|
|||
* right side of the tab bar */
|
||||
struct ButtonLayout {
|
||||
WidgetNodeType mType;
|
||||
bool mAtRight;
|
||||
};
|
||||
|
||||
/*** General library functions ***/
|
||||
|
|
|
@ -1293,9 +1293,6 @@ void nsLookAndFeel::EnsureInit() {
|
|||
|
||||
if (pos) {
|
||||
*pos = i;
|
||||
if (layout.mAtRight) {
|
||||
*pos += TOOLBAR_BUTTONS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2229,10 +2229,13 @@ STATIC_ATOMS = [
|
|||
Atom("_moz_gtk_csd_available", "-moz-gtk-csd-available"),
|
||||
Atom("_moz_gtk_csd_titlebar_radius", "-moz-gtk-csd-titlebar-radius"),
|
||||
Atom("_moz_gtk_csd_minimize_button", "-moz-gtk-csd-minimize-button"),
|
||||
Atom("_moz_gtk_csd_minimize_button_position", "-moz-gtk-csd-minimize-button-position"),
|
||||
Atom("_moz_gtk_csd_maximize_button", "-moz-gtk-csd-maximize-button"),
|
||||
Atom("_moz_gtk_csd_maximize_button_position", "-moz-gtk-csd-maximize-button-position"),
|
||||
Atom("_moz_gtk_csd_close_button", "-moz-gtk-csd-close-button"),
|
||||
Atom("_moz_gtk_csd_close_button_position", "-moz-gtk-csd-close-button-position"),
|
||||
Atom("_moz_gtk_csd_reversed_placement", "-moz-gtk-csd-reversed-placement"),
|
||||
Atom("_moz_gtk_menu_radius", "-moz-gtk-menu-radius"),
|
||||
Atom("_moz_gtk_csd_menu_radius", "-moz-gtk-csd-menu-radius"),
|
||||
Atom("_moz_proton", "-moz-proton"),
|
||||
Atom("_moz_proton_places_tooltip", "-moz-proton-places-tooltip"),
|
||||
Atom("_moz_system_dark_theme", "-moz-system-dark-theme"),
|
||||
|
|
Загрузка…
Ссылка в новой задаче