Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fn key to Modifiers #5237

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/eframe/src/web/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ pub fn translate_key(key: &str) -> Option<egui::Key> {

pub fn modifiers_from_kb_event(event: &web_sys::KeyboardEvent) -> egui::Modifiers {
egui::Modifiers {
function: event.key() == "Fn",
alt: event.alt_key(),
ctrl: event.ctrl_key(),
shift: event.shift_key(),
Expand All @@ -167,6 +168,7 @@ pub fn modifiers_from_kb_event(event: &web_sys::KeyboardEvent) -> egui::Modifier

pub fn modifiers_from_mouse_event(event: &web_sys::MouseEvent) -> egui::Modifiers {
egui::Modifiers {
function: event.get_modifier_state("Fn"),
alt: event.alt_key(),
ctrl: event.ctrl_key(),
shift: event.shift_key(),
Expand All @@ -183,6 +185,7 @@ pub fn modifiers_from_mouse_event(event: &web_sys::MouseEvent) -> egui::Modifier

pub fn modifiers_from_wheel_event(event: &web_sys::WheelEvent) -> egui::Modifiers {
egui::Modifiers {
function: event.get_modifier_state("Fn"),
alt: event.alt_key(),
ctrl: event.ctrl_key(),
shift: event.shift_key(),
Expand Down
28 changes: 20 additions & 8 deletions crates/egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,15 +394,27 @@ impl State {
consumed: false,
}
} else {
self.on_keyboard_input(event);
let function = event.logical_key
== winit::keyboard::Key::Named(winit::keyboard::NamedKey::Fn);

// When pressing the Tab key, egui focuses the first focusable element, hence Tab always consumes.
let consumed = self.egui_ctx.wants_keyboard_input()
|| event.logical_key
== winit::keyboard::Key::Named(winit::keyboard::NamedKey::Tab);
EventResponse {
repaint: true,
consumed,
self.egui_input.modifiers.function = function;

if function {
EventResponse {
repaint: true,
consumed: false,
}
} else {
self.on_keyboard_input(event);

// When pressing the Tab key, egui focuses the first focusable element, hence Tab always consumes.
let consumed = self.egui_ctx.wants_keyboard_input()
|| event.logical_key
== winit::keyboard::Key::Named(winit::keyboard::NamedKey::Tab);
EventResponse {
repaint: true,
consumed,
}
}
}
}
Expand Down
52 changes: 46 additions & 6 deletions crates/egui/src/data/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,9 @@ pub const NUM_POINTER_BUTTONS: usize = 5;
#[derive(Clone, Copy, Default, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Modifiers {
/// The fn key (or the 🌐︎ Globe key on Mac).
pub function: bool,

/// Either of the alt keys are down (option ⌥ on Mac).
pub alt: bool,

Expand Down Expand Up @@ -613,6 +616,7 @@ impl std::fmt::Debug for Modifiers {
}

let Self {
function,
alt,
ctrl,
shift,
Expand All @@ -621,6 +625,9 @@ impl std::fmt::Debug for Modifiers {
} = *self;

let mut debug = f.debug_struct("Modifiers");
if function {
debug.field("function", &true);
}
if alt {
debug.field("alt", &true);
}
Expand All @@ -642,28 +649,40 @@ impl std::fmt::Debug for Modifiers {

impl Modifiers {
pub const NONE: Self = Self {
function: false,
alt: false,
ctrl: false,
shift: false,
mac_cmd: false,
command: false,
};

pub const FN: Self = Self {
function: true,
alt: false,
ctrl: false,
shift: false,
mac_cmd: false,
command: false,
};
pub const ALT: Self = Self {
function: false,
alt: true,
ctrl: false,
shift: false,
mac_cmd: false,
command: false,
};
pub const CTRL: Self = Self {
function: false,
alt: false,
ctrl: true,
shift: false,
mac_cmd: false,
command: false,
};
pub const SHIFT: Self = Self {
function: false,
alt: false,
ctrl: false,
shift: true,
Expand All @@ -673,6 +692,7 @@ impl Modifiers {

/// The Mac ⌘ Command key
pub const MAC_CMD: Self = Self {
function: false,
alt: false,
ctrl: false,
shift: false,
Expand All @@ -682,6 +702,7 @@ impl Modifiers {

/// On Mac: ⌘ Command key, elsewhere: Ctrl key
pub const COMMAND: Self = Self {
function: false,
alt: false,
ctrl: false,
shift: false,
Expand All @@ -707,6 +728,7 @@ impl Modifiers {
#[inline]
pub const fn plus(self, rhs: Self) -> Self {
Self {
function: self.function | rhs.function,
alt: self.alt | rhs.alt,
ctrl: self.ctrl | rhs.ctrl,
shift: self.shift | rhs.shift,
Expand All @@ -727,19 +749,19 @@ impl Modifiers {

#[inline]
pub fn all(&self) -> bool {
self.alt && self.ctrl && self.shift && self.command
self.function && self.alt && self.ctrl && self.shift && self.command
}

/// Is shift the only pressed button?
#[inline]
pub fn shift_only(&self) -> bool {
self.shift && !(self.alt || self.command)
self.shift && !(self.function || self.alt || self.command)
}

/// true if only [`Self::ctrl`] or only [`Self::mac_cmd`] is pressed.
#[inline]
pub fn command_only(&self) -> bool {
!self.alt && !self.shift && self.command
!self.function && !self.alt && !self.shift && self.command
}

/// Checks that the `ctrl/cmd` matches, and that the `shift/alt` of the argument is a subset
Expand Down Expand Up @@ -778,6 +800,9 @@ impl Modifiers {
/// assert!(!Modifiers::COMMAND.matches_logically(Modifiers::MAC_CMD));
/// ```
pub fn matches_logically(&self, pattern: Self) -> bool {
if pattern.function && !self.function {
return false;
}
if pattern.alt && !self.alt {
return false;
}
Expand Down Expand Up @@ -821,7 +846,10 @@ impl Modifiers {
/// ```
pub fn matches_exact(&self, pattern: Self) -> bool {
// alt and shift must always match the pattern:
if pattern.alt != self.alt || pattern.shift != self.shift {
if pattern.function != self.function
|| pattern.alt != self.alt
|| pattern.shift != self.shift
{
return false;
}

Expand Down Expand Up @@ -891,13 +919,20 @@ impl Modifiers {
}

let Self {
function,
alt,
ctrl,
shift,
mac_cmd,
command,
} = *self;

if function && query.function {
return self.contains(Self {
function: false,
..query
});
}
if alt && query.alt {
return self.contains(Self {
alt: false,
Expand Down Expand Up @@ -948,6 +983,7 @@ impl std::ops::BitOr for Modifiers {
pub struct ModifierNames<'a> {
pub is_short: bool,

pub function: &'a str,
pub alt: &'a str,
pub ctrl: &'a str,
pub shift: &'a str,
Expand All @@ -959,9 +995,10 @@ pub struct ModifierNames<'a> {
}

impl ModifierNames<'static> {
/// ⌥ ⌃ ⇧ ⌘ - NOTE: not supported by the default egui font.
/// 🌐︎ ⌥ ⌃ ⇧ ⌘ - NOTE: not supported by the default egui font.
pub const SYMBOLS: Self = Self {
is_short: true,
function: "🌐︎",
alt: "⌥",
ctrl: "⌃",
shift: "⇧",
Expand All @@ -970,9 +1007,10 @@ impl ModifierNames<'static> {
concat: "",
};

/// Alt, Ctrl, Shift, Cmd
/// Fn, Alt, Ctrl, Shift, Cmd
pub const NAMES: Self = Self {
is_short: false,
function: "Fn",
alt: "Alt",
ctrl: "Ctrl",
shift: "Shift",
Expand All @@ -998,11 +1036,13 @@ impl<'a> ModifierNames<'a> {
if is_mac {
append_if(modifiers.ctrl, self.ctrl);
append_if(modifiers.shift, self.shift);
append_if(modifiers.function, self.function);
append_if(modifiers.alt, self.mac_alt);
append_if(modifiers.mac_cmd || modifiers.command, self.mac_cmd);
} else {
append_if(modifiers.ctrl || modifiers.command, self.ctrl);
append_if(modifiers.alt, self.alt);
append_if(modifiers.function, self.function);
append_if(modifiers.shift, self.shift);
}

Expand Down