mirror of
https://github.com/labwc/labwc.git
synced 2026-02-05 04:06:33 -05:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
fd6d62eaed
18 changed files with 248 additions and 75 deletions
|
|
@ -51,9 +51,13 @@ Actions are used in menus and keyboard/mouse bindings.
|
|||
another window or screen edge. If set to "no", only move to
|
||||
the next screen edge. Default is yes.
|
||||
|
||||
*<action name="Resize" />*
|
||||
*<action name="Resize" direction="value" />*
|
||||
Begin interactive resize of window under cursor.
|
||||
|
||||
*direction* [up|down|left|right|up-left|up-right|down-left|down-right]
|
||||
Edge or corner from which to start resizing. If this is not provided,
|
||||
the direction is inferred from the cursor position.
|
||||
|
||||
*<action name="ResizeRelative" left="" right="" top="" bottom="" />*
|
||||
Resize window relative to its current size. Values of left, right,
|
||||
top or bottom tell how much to resize on that edge of window,
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ this is for compatibility with Openbox.
|
|||
</windowSwitcher>
|
||||
```
|
||||
|
||||
*<windowSwitcher preview="" outlines="" allWorkspaces="" unshade="">*
|
||||
*<windowSwitcher preview="" outlines="" allWorkspaces="" unshade="" order="">*
|
||||
*preview* [yes|no] Preview the contents of the selected window when
|
||||
switching between windows. Default is yes.
|
||||
|
||||
|
|
@ -363,6 +363,11 @@ this is for compatibility with Openbox.
|
|||
*unshade* [yes|no] Temporarily unshade windows when switching between
|
||||
them and permanently unshade on the final selection. Default is yes.
|
||||
|
||||
*order* [focus|age] The order in which windows are cycled. *focus* cycles by
|
||||
recent focus history, starting with the previously focused window. *age* cycles
|
||||
by creation/open order, a stable taskbar-style ordering that doesn’t change on
|
||||
focus. Default is *focus*.
|
||||
|
||||
*<windowSwitcher><osd show="" style="" output="" thumbnailLabelFormat="" />*
|
||||
*show* [yes|no] Draw the OnScreenDisplay when switching between
|
||||
windows. Default is yes.
|
||||
|
|
@ -498,13 +503,16 @@ activated with SnapToEdge actions or, optionally, by dragging windows to the
|
|||
edges of an output. Edge snapping causes a window to occupy half of its output,
|
||||
extending outward from the snapped edge.
|
||||
|
||||
*<snapping><range>*++
|
||||
*<snapping><range><inner>*++
|
||||
*<snapping><range><outer>*++
|
||||
*<snapping><cornerRange>*
|
||||
If an interactive move ends with the cursor within *<range>* pixels of an
|
||||
output edge, the window is snapped to the edge. If it's also within
|
||||
*<cornerRange>* pixels of an output corner, the window is snapped to the
|
||||
corner instead. A *<range>* of 0 disables snapping.
|
||||
Default is 10 for *<range>* and 50 for *<cornerRange>*.
|
||||
If an interactive move ends with the cursor within *inner* or *outer* pixels
|
||||
of an output edge, the window is snapped to the edge. *inner* edges are edges
|
||||
with an adjacent output and *outer* edges are edges without an adjacent output.
|
||||
If it's also within *<cornerRange>* pixels of an output corner, the window is
|
||||
snapped to the corner instead.
|
||||
If *inner* and *outer* is 0, snapping is disabled.
|
||||
Default is 10 for *<range><inner>* and *<range><outer>*, and 50 for *<cornerRange>*.
|
||||
|
||||
*<snapping><overlay><enabled>* [yes|no]
|
||||
Show an overlay when snapping to a window to an edge. Default is yes.
|
||||
|
|
@ -700,6 +708,45 @@ extending outward from the snapped edge.
|
|||
invisible zones just beyond the window that serve as click targets for
|
||||
mouse actions. Default is 8.
|
||||
|
||||
# INPUT CONFIGURATION
|
||||
|
||||
This section describes configuration of input devices including:
|
||||
|
||||
- Keyboards
|
||||
- Mice
|
||||
- Touchpads (sometimes referred to as laptop trackpads)
|
||||
- Touchscreens
|
||||
- Tablets
|
||||
- Tablet tools (like stylus pens)
|
||||
|
||||
It aims to clarify related terminology and separation of concerns.
|
||||
|
||||
Keyboards are configured in the *<keyboard>* section below and are simple in
|
||||
this regard.
|
||||
|
||||
Touchpads and mice are harder. They are both considered to be *pointer* devices
|
||||
by the compositor, and can be configured in the *<mouse>* and *<libinput>*
|
||||
sections. Any setting that is supported by libinput is configured in the
|
||||
*<libinput>* section, and anything else is in *<mouse>*. Touchpad devices can
|
||||
generate gesture events, like swipe and pinch. There are some related settings
|
||||
(e.g. *threeFingerDrag* and *twoFingerScroll*) in the *<libinput>* section.
|
||||
|
||||
In the Wayland Compositor domain, events associated with touchscreens are
|
||||
sometimes simply referred to as *touch* events. Touchscreens can be configured
|
||||
in both the *<touch>* and *<libinput>* sections. Note that touchscreen gestures
|
||||
are not interpreted by libinput, nor labwc. Any touch point is passed to the
|
||||
client (application) for any interpretation of gestures.
|
||||
|
||||
Tablets are considered special by libinput although in the eyes of the Wayland
|
||||
protocol they are merely a *touch* capability. Tablets and associated tablet
|
||||
tools are configured in the *<tablet>*, *<tablettool>* and *<libinput>*
|
||||
sections. Note that the term *tablet* in libinput (and labwc) refers to graphics
|
||||
tablets only (e.g. Wacom Intuos), not to tablet devices like the Apple iPad.
|
||||
|
||||
References:
|
||||
- https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html
|
||||
- https://wayland.freedesktop.org/libinput/doc/latest/gestures.html
|
||||
|
||||
## KEYBOARD
|
||||
|
||||
*<keyboard><numlock>* [on|off]
|
||||
|
|
@ -808,6 +855,9 @@ extending outward from the snapped edge.
|
|||
|
||||
## MOUSE
|
||||
|
||||
This section relates to mice and touchpads - which are both considered pointer
|
||||
input-devices by the Wayland protocol.
|
||||
|
||||
*<mouse><doubleClickTime>*
|
||||
Set double click time in milliseconds. Default is 500.
|
||||
|
||||
|
|
@ -918,6 +968,11 @@ extending outward from the snapped edge.
|
|||
|
||||
## TOUCH
|
||||
|
||||
This section relates to touchscreens and *not* touchpads.
|
||||
|
||||
Note: To rotate touch events with output rotation, use the libinput
|
||||
*calibrationMatrix* setting.
|
||||
|
||||
```
|
||||
<touch deviceName="" mapToOutput="" mouseEmulation="no"/>
|
||||
```
|
||||
|
|
@ -1080,14 +1135,9 @@ extending outward from the snapped edge.
|
|||
attribute is provided, a 'default' device profile will created that will
|
||||
act as the fallback for all libinput devices. Category can be set to any
|
||||
of the following types:
|
||||
- *touch* - Devices which have a defined width/height, but do not
|
||||
support multitouch (i.e. they cannot track multiple locations where
|
||||
the screen has been touched). Drawing tablets typically fall into this
|
||||
type.
|
||||
- *touchpad* - Same as 'touch' but support multitouch. This typically
|
||||
includes laptop track pads with two-finger scroll and swipe gestures.
|
||||
- *non-touch* - Anything not described above, for example traditional
|
||||
mouse pointers.
|
||||
- *touch* - Includes touchscreens and drawing-tablets.
|
||||
- *touchpad* - Includes touchpads (also known as laptop trackpads)
|
||||
- *non-touch* - Includes traditional mice
|
||||
- *default* - Defines a device-category applicable to all devices not
|
||||
matched by anything else. This can be useful for a fallback, or if you
|
||||
want the same settings to be applied to all devices.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<labwc_config>
|
||||
|
||||
<theme>
|
||||
<name></name>
|
||||
<name>Clearlooks-3.4</name>
|
||||
<cornerRadius>8</cornerRadius>
|
||||
<font name="sans" size="10" />
|
||||
</theme>
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@
|
|||
|
||||
<!-- <font><theme> can be defined without an attribute to set all places -->
|
||||
<theme>
|
||||
<name></name>
|
||||
<icon></icon>
|
||||
<!-- <name>Numix</name> -->
|
||||
<!-- <icon>breeze</icon> -->
|
||||
<fallbackAppIcon>labwc</fallbackAppIcon>
|
||||
<titlebar>
|
||||
<layout>icon:iconify,max,close</layout>
|
||||
|
|
@ -161,8 +161,8 @@
|
|||
</focus>
|
||||
|
||||
<snapping>
|
||||
<!-- Set range to 0 to disable window snapping completely -->
|
||||
<range>10</range>
|
||||
<!-- Set inner and outer range to 0 to disable window snapping completely -->
|
||||
<range inner="10" outer="10" />
|
||||
<cornerRange>50</cornerRange>
|
||||
<overlay enabled="yes">
|
||||
<delay inner="500" outer="500" />
|
||||
|
|
@ -218,9 +218,9 @@
|
|||
space automatically, so <margin> is only intended for other, specialist
|
||||
cases.
|
||||
|
||||
If output is left empty, the margin will be applied to all outputs.
|
||||
If 'output' is not provided, the margin will be applied to all outputs.
|
||||
|
||||
<margin top="" bottom="" left="" right="" output="" />
|
||||
<margin top="10" bottom="10" left="10" right="10" output="HDMI-A-1" />
|
||||
-->
|
||||
|
||||
<!-- Percent based regions based on output usable area, % char is required -->
|
||||
|
|
@ -525,7 +525,11 @@
|
|||
If mouseEmulation is enabled, all touch up/down/motion events are
|
||||
translated to mouse button and motion events.
|
||||
-->
|
||||
<touch deviceName="" mapToOutput="" mouseEmulation="no"/>
|
||||
<touch>
|
||||
<!-- <deviceName>ELAN2514:00 04F3:2AF1<deviceName> -->
|
||||
<!-- <mapToOutput>HDMI-A-1</mapToOutput> -->
|
||||
<mouseEmulation>no</mouseEmulation>
|
||||
</touch>
|
||||
|
||||
<!--
|
||||
The tablet cursor movement can be restricted to a single output.
|
||||
|
|
@ -552,7 +556,8 @@
|
|||
When using mouse emulation, the pen tip [tip] and the stylus buttons
|
||||
can be set to any available mouse button [Left|Right|Middle|..|Task].
|
||||
-->
|
||||
<tablet mapToOutput="" rotate="0" mouseEmulation="no">
|
||||
<tablet rotate="0" mouseEmulation="no">
|
||||
<!-- <mapToOutput>HDMI-A-1</mapToOutput> -->
|
||||
<!-- Active area dimensions are in mm -->
|
||||
<area top="0.0" left="0.0" width="0.0" height="0.0" />
|
||||
<map button="Tip" to="Left" />
|
||||
|
|
@ -583,10 +588,11 @@
|
|||
- accelProfile [flat|adaptive]
|
||||
- tapButtonMap [lrm|lmr]
|
||||
- clickMethod [none|buttonAreas|clickfinger]
|
||||
- scrollMethod [twoFinger|edge|none]
|
||||
- sendEventsMode [yes|no|disabledOnExternalMouse]
|
||||
- calibrationMatrix [six float values split by space]
|
||||
- scrollFactor [float]
|
||||
|
||||
|
||||
The following <libinput>...</libinput> block may not be complete for
|
||||
your requirements. Default values are device specific. Only set an option
|
||||
if you require to override the default. Valid values must be inserted.
|
||||
|
|
@ -595,21 +601,21 @@
|
|||
|
||||
<libinput>
|
||||
<device category="default">
|
||||
<naturalScroll></naturalScroll>
|
||||
<leftHanded></leftHanded>
|
||||
<pointerSpeed></pointerSpeed>
|
||||
<accelProfile></accelProfile>
|
||||
<!-- <naturalScroll>no</naturalScroll> -->
|
||||
<!-- <leftHanded>no</leftHanded> -->
|
||||
<!-- <pointerSpeed>0.0</pointerSpeed> -->
|
||||
<!-- <accelProfile>adaptive</accelProfile> -->
|
||||
<tap>yes</tap>
|
||||
<tapButtonMap></tapButtonMap>
|
||||
<tapAndDrag></tapAndDrag>
|
||||
<dragLock></dragLock>
|
||||
<threeFingerDrag></threeFingerDrag>
|
||||
<middleEmulation></middleEmulation>
|
||||
<disableWhileTyping></disableWhileTyping>
|
||||
<clickMethod></clickMethod>
|
||||
<scrollMethod></scrollMethod>
|
||||
<sendEventsMode></sendEventsMode>
|
||||
<calibrationMatrix></calibrationMatrix>
|
||||
<!-- <tapButtonMap>lrm</tapButtonMap> -->
|
||||
<!-- <tapAndDrag>yes</tapAndDrag> -->
|
||||
<!-- <dragLock>yes</dragLock> -->
|
||||
<!-- <threeFingerDrag>yes</threeFingerDrag> -->
|
||||
<!-- <middleEmulation>no</middleEmulation> -->
|
||||
<!-- <disableWhileTyping>yes</disableWhileTyping> -->
|
||||
<!-- <clickMethod>buttonAreas</clickMethod> -->
|
||||
<!-- <scrollMethod>twofinger</scrollMethod> -->
|
||||
<!-- <sendEventsMode>yes</sendEventsMode> -->
|
||||
<!-- <calibrationMatrix>1 0 0 0 1 0</calibrationMatrix> -->
|
||||
<scrollFactor>1.0</scrollFactor>
|
||||
</device>
|
||||
</libinput>
|
||||
|
|
@ -678,7 +684,7 @@
|
|||
<height>400</height>
|
||||
<initScale>2.0</initScale>
|
||||
<increment>0.2</increment>
|
||||
<useFilter>true</useFilter>
|
||||
<useFilter>yes</useFilter>
|
||||
</magnifier>
|
||||
|
||||
</labwc_config>
|
||||
|
|
|
|||
|
|
@ -151,7 +151,8 @@ struct rcxml {
|
|||
int unmaximize_threshold;
|
||||
|
||||
/* window snapping */
|
||||
int snap_edge_range;
|
||||
int snap_edge_range_inner;
|
||||
int snap_edge_range_outer;
|
||||
int snap_edge_corner_range;
|
||||
bool snap_overlay_enabled;
|
||||
int snap_overlay_delay_inner;
|
||||
|
|
@ -185,6 +186,7 @@ struct rcxml {
|
|||
enum cycle_osd_style style;
|
||||
enum cycle_osd_output_criteria output_criteria;
|
||||
char *thumbnail_label_format;
|
||||
enum window_switcher_order order;
|
||||
} window_switcher;
|
||||
|
||||
struct wl_list window_rules; /* struct window_rule.link */
|
||||
|
|
|
|||
|
|
@ -107,6 +107,11 @@ enum lab_window_type {
|
|||
LAB_WINDOW_TYPE_LEN
|
||||
};
|
||||
|
||||
enum window_switcher_order {
|
||||
WINDOW_SWITCHER_ORDER_FOCUS,
|
||||
WINDOW_SWITCHER_ORDER_AGE,
|
||||
};
|
||||
|
||||
enum cycle_osd_style {
|
||||
CYCLE_OSD_STYLE_CLASSIC,
|
||||
CYCLE_OSD_STYLE_THUMBNAIL,
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ struct server {
|
|||
struct wl_listener xdg_toplevel_icon_set_icon;
|
||||
|
||||
struct wl_list views;
|
||||
uint64_t next_view_creation_id;
|
||||
struct wl_list unmanaged_surfaces;
|
||||
|
||||
struct seat seat;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ struct node_descriptor {
|
|||
* @type: node descriptor type
|
||||
* @view: associated view
|
||||
* @data: struct to point to as follows:
|
||||
* - LAB_NODE_CYCLE_OSD_ITEM struct cycle_osd_item
|
||||
* - LAB_NODE_LAYER_SURFACE struct lab_layer_surface
|
||||
* - LAB_NODE_LAYER_POPUP struct lab_layer_popup
|
||||
* - LAB_NODE_MENUITEM struct menuitem
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ struct view {
|
|||
|
||||
bool mapped;
|
||||
bool been_mapped;
|
||||
uint64_t creation_id;
|
||||
enum lab_ssd_mode ssd_mode;
|
||||
enum ssd_preference ssd_preference;
|
||||
bool shaded;
|
||||
|
|
|
|||
27
src/action.c
27
src/action.c
|
|
@ -414,6 +414,20 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
|
|||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_RESIZE:
|
||||
if (!strcmp(argument, "direction")) {
|
||||
enum lab_edge edge = lab_edge_parse(content,
|
||||
/*tiled*/ true, /*any*/ false);
|
||||
if (edge == LAB_EDGE_NONE || edge == LAB_EDGE_CENTER) {
|
||||
wlr_log(WLR_ERROR,
|
||||
"Invalid argument for action %s: '%s' (%s)",
|
||||
action_names[action->type], argument, content);
|
||||
} else {
|
||||
action_arg_add_int(action, argument, edge);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_RESIZE_RELATIVE:
|
||||
if (!strcmp(argument, "left") || !strcmp(argument, "right") ||
|
||||
!strcmp(argument, "top") || !strcmp(argument, "bottom")) {
|
||||
|
|
@ -1223,8 +1237,17 @@ run_action(struct view *view, struct server *server, struct action *action,
|
|||
break;
|
||||
case ACTION_TYPE_RESIZE:
|
||||
if (view) {
|
||||
enum lab_edge resize_edges = cursor_get_resize_edges(
|
||||
server->seat.cursor, ctx);
|
||||
/*
|
||||
* If a direction was specified in the config, honour it.
|
||||
* Otherwise, fall back to determining the resize edges from
|
||||
* the current cursor position (existing behaviour).
|
||||
*/
|
||||
enum lab_edge resize_edges =
|
||||
action_get_int(action, "direction", LAB_EDGE_NONE);
|
||||
if (resize_edges == LAB_EDGE_NONE) {
|
||||
resize_edges = cursor_get_resize_edges(
|
||||
server->seat.cursor, ctx);
|
||||
}
|
||||
interactive_begin(view, LAB_INPUT_STATE_RESIZE,
|
||||
resize_edges);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -714,6 +714,8 @@ fill_libinput_category(xmlNode *node)
|
|||
char *key, *content;
|
||||
LAB_XML_FOR_EACH(node, child, key, content) {
|
||||
if (string_null_or_empty(content)) {
|
||||
wlr_log(WLR_ERROR, "Empty string is not allowed for "
|
||||
"<libinput><device><%s>. Ignoring.", key);
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(key, "category")) {
|
||||
|
|
@ -1076,7 +1078,8 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
return true;
|
||||
|
||||
} else if (str_space_only(content)) {
|
||||
/* ignore empty leaf nodes other than above */
|
||||
wlr_log(WLR_ERROR, "Empty string is not allowed for %s. "
|
||||
"Ignoring.", nodename);
|
||||
|
||||
/* handle non-empty leaf nodes */
|
||||
} else if (!strcmp(nodename, "decoration.core")) {
|
||||
|
|
@ -1177,7 +1180,14 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
} else if (!strcasecmp(nodename, "unMaximizeThreshold.resistance")) {
|
||||
rc.unmaximize_threshold = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "range.snapping")) {
|
||||
rc.snap_edge_range = atoi(content);
|
||||
rc.snap_edge_range_inner = atoi(content);
|
||||
rc.snap_edge_range_outer = atoi(content);
|
||||
wlr_log(WLR_ERROR, "<snapping><range> is deprecated. "
|
||||
"Use <snapping><range inner=\"\" outer=\"\"> instead.");
|
||||
} else if (!strcasecmp(nodename, "inner.range.snapping")) {
|
||||
rc.snap_edge_range_inner = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "outer.range.snapping")) {
|
||||
rc.snap_edge_range_outer = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "cornerRange.snapping")) {
|
||||
rc.snap_edge_corner_range = atoi(content);
|
||||
} else if (!strcasecmp(nodename, "enabled.overlay.snapping")) {
|
||||
|
|
@ -1230,6 +1240,15 @@ entry(xmlNode *node, char *nodename, char *content)
|
|||
wlr_log(WLR_ERROR, "Invalid windowSwitcher output %s: "
|
||||
"should be one of all|focused|cursor", content);
|
||||
}
|
||||
} else if (!strcasecmp(nodename, "order.windowSwitcher")) {
|
||||
if (!strcasecmp(content, "focus")) {
|
||||
rc.window_switcher.order = WINDOW_SWITCHER_ORDER_FOCUS;
|
||||
} else if (!strcasecmp(content, "age")) {
|
||||
rc.window_switcher.order = WINDOW_SWITCHER_ORDER_AGE;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Invalid windowSwitcher order %s: "
|
||||
"should be one of focus|age", content);
|
||||
}
|
||||
|
||||
/* The following two are for backward compatibility only. */
|
||||
} else if (!strcasecmp(nodename, "show.windowSwitcher")) {
|
||||
|
|
@ -1456,7 +1475,8 @@ rcxml_init(void)
|
|||
rc.unsnap_threshold = 20;
|
||||
rc.unmaximize_threshold = 150;
|
||||
|
||||
rc.snap_edge_range = 10;
|
||||
rc.snap_edge_range_inner = 10;
|
||||
rc.snap_edge_range_outer = 10;
|
||||
rc.snap_edge_corner_range = 50;
|
||||
rc.snap_overlay_enabled = true;
|
||||
rc.snap_overlay_delay_inner = 500;
|
||||
|
|
@ -1474,6 +1494,7 @@ rcxml_init(void)
|
|||
rc.window_switcher.criteria = LAB_VIEW_CRITERIA_CURRENT_WORKSPACE
|
||||
| LAB_VIEW_CRITERIA_ROOT_TOPLEVEL
|
||||
| LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER;
|
||||
rc.window_switcher.order = WINDOW_SWITCHER_ORDER_FOCUS;
|
||||
|
||||
rc.resize_indicator = LAB_RESIZE_INDICATOR_NEVER;
|
||||
rc.resize_draw_contents = true;
|
||||
|
|
@ -1648,9 +1669,8 @@ load_default_window_switcher_fields(void)
|
|||
#endif
|
||||
};
|
||||
|
||||
struct cycle_osd_field *field;
|
||||
for (size_t i = 0; i < ARRAY_SIZE(fields); i++) {
|
||||
field = znew(*field);
|
||||
struct cycle_osd_field *field = znew(*field);
|
||||
field->content = fields[i].content;
|
||||
field->width = fields[i].width;
|
||||
wl_list_append(&rc.window_switcher.fields, &field->link);
|
||||
|
|
|
|||
|
|
@ -276,13 +276,31 @@ create_osd_on_output(struct output *output)
|
|||
assert(output->cycle_osd.tree);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_view_ordered_by_age(struct wl_list *views, struct view *new_view)
|
||||
{
|
||||
struct wl_list *link = views;
|
||||
struct view *view;
|
||||
wl_list_for_each(view, views, cycle_link) {
|
||||
if (view->creation_id >= new_view->creation_id) {
|
||||
break;
|
||||
}
|
||||
link = &view->cycle_link;
|
||||
}
|
||||
wl_list_insert(link, &new_view->cycle_link);
|
||||
}
|
||||
|
||||
/* Return false on failure */
|
||||
static bool
|
||||
init_cycle(struct server *server)
|
||||
{
|
||||
struct view *view;
|
||||
for_each_view(view, &server->views, rc.window_switcher.criteria) {
|
||||
wl_list_append(&server->cycle.views, &view->cycle_link);
|
||||
if (rc.window_switcher.order == WINDOW_SWITCHER_ORDER_AGE) {
|
||||
insert_view_ordered_by_age(&server->cycle.views, view);
|
||||
} else {
|
||||
wl_list_append(&server->cycle.views, &view->cycle_link);
|
||||
}
|
||||
}
|
||||
if (wl_list_empty(&server->cycle.views)) {
|
||||
wlr_log(WLR_DEBUG, "no views to switch between");
|
||||
|
|
|
|||
|
|
@ -144,7 +144,6 @@ cycle_osd_classic_create(struct output *output)
|
|||
y += switcher_theme->item_height;
|
||||
}
|
||||
|
||||
struct buf buf = BUF_INIT;
|
||||
int nr_fields = wl_list_length(&rc.window_switcher.fields);
|
||||
|
||||
/* This is the width of the area available for text fields */
|
||||
|
|
@ -194,9 +193,9 @@ cycle_osd_classic_create(struct output *output)
|
|||
/* Highlight around selected window's item */
|
||||
struct lab_scene_rect_options highlight_opts = {
|
||||
.border_colors = (float *[1]) {active_border_color},
|
||||
.bg_color = active_bg_color,
|
||||
.nr_borders = 1,
|
||||
.border_width = switcher_theme->item_active_border_width,
|
||||
.bg_color = active_bg_color,
|
||||
.width = w - 2 * padding,
|
||||
.height = switcher_theme->item_height,
|
||||
};
|
||||
|
|
@ -216,7 +215,6 @@ cycle_osd_classic_create(struct output *output)
|
|||
|
||||
y += switcher_theme->item_height;
|
||||
}
|
||||
buf_reset(&buf);
|
||||
|
||||
error:;
|
||||
/* Center OSD */
|
||||
|
|
|
|||
|
|
@ -251,6 +251,9 @@ err:
|
|||
* (e.g. "thunderbird" matches "org.mozilla.Thunderbird.desktop"
|
||||
* and "XTerm" matches "xterm.desktop"). This is not per any spec
|
||||
* but is needed to find icons for existing applications.
|
||||
*
|
||||
* The second loop tries to match more partial strings, for
|
||||
* example "gimp-2.0" would match "org.something.gimp.desktop".
|
||||
*/
|
||||
static struct sfdo_desktop_entry *
|
||||
get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id)
|
||||
|
|
@ -258,6 +261,7 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id)
|
|||
size_t n_entries;
|
||||
struct sfdo_desktop_entry **entries = sfdo_desktop_db_get_entries(db, &n_entries);
|
||||
|
||||
/* Would match "org.foobar.xterm" when given app-id "XTerm" */
|
||||
for (size_t i = 0; i < n_entries; i++) {
|
||||
struct sfdo_desktop_entry *entry = entries[i];
|
||||
const char *desktop_id = sfdo_desktop_entry_get_id(entry, NULL);
|
||||
|
|
@ -266,6 +270,8 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id)
|
|||
const char *desktop_id_base = dot ? (dot + 1) : desktop_id;
|
||||
|
||||
if (!strcasecmp(app_id, desktop_id_base)) {
|
||||
wlr_log(WLR_DEBUG, "'%s' to '%s.desktop' via case-insensitive match",
|
||||
app_id, desktop_id);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
|
@ -278,20 +284,31 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id)
|
|||
const char *wm_class =
|
||||
sfdo_desktop_entry_get_startup_wm_class(entry, NULL);
|
||||
if (wm_class && !strcasecmp(app_id, wm_class)) {
|
||||
wlr_log(WLR_DEBUG, "'%s' to '%s.desktop' via StartupWMClass",
|
||||
app_id, desktop_id);
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try matching partial strings - catches GIMP, among others */
|
||||
/* Would match "org.foobar.xterm-unicode" when given app-id "XTerm" */
|
||||
const int app_id_len = strlen(app_id);
|
||||
for (size_t i = 0; i < n_entries; i++) {
|
||||
struct sfdo_desktop_entry *entry = entries[i];
|
||||
const char *desktop_id = sfdo_desktop_entry_get_id(entry, NULL);
|
||||
const char *dot = strrchr(desktop_id, '.');
|
||||
const char *desktop_id_base = dot ? (dot + 1) : desktop_id;
|
||||
int alen = strlen(app_id);
|
||||
int dlen = strlen(desktop_id_base);
|
||||
|
||||
if (!strncasecmp(app_id, desktop_id_base, alen > dlen ? dlen : alen)) {
|
||||
const int dlen = strlen(desktop_id_base);
|
||||
const int cmp_len = MIN(app_id_len, dlen);
|
||||
if (cmp_len < 3) {
|
||||
/*
|
||||
* Without this check, app-id "foot" would match
|
||||
* "something.f" and any app-id would match "R.E.P.O."
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
if (!strncasecmp(app_id, desktop_id_base, cmp_len)) {
|
||||
wlr_log(WLR_DEBUG, "'%s' to '%s.desktop' via partial match",
|
||||
app_id, desktop_id);
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
|
@ -304,10 +321,14 @@ get_desktop_entry(struct sfdo *sfdo, const char *app_id)
|
|||
{
|
||||
struct sfdo_desktop_entry *entry = sfdo_desktop_db_get_entry_by_id(
|
||||
sfdo->desktop_db, app_id, SFDO_NT);
|
||||
if (!entry) {
|
||||
entry = get_db_entry_by_id_fuzzy(sfdo->desktop_db, app_id);
|
||||
if (entry) {
|
||||
wlr_log(WLR_DEBUG, "matched '%s.desktop' via exact match", app_id);
|
||||
return entry;
|
||||
}
|
||||
entry = get_db_entry_by_id_fuzzy(sfdo->desktop_db, app_id);
|
||||
if (!entry) {
|
||||
wlr_log(WLR_DEBUG, "failed to find .desktop file for '%s'", app_id);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -840,10 +840,12 @@ apply_constraint(struct seat *seat, struct wlr_pointer *pointer, double *x, doub
|
|||
if (!seat->server->active_view) {
|
||||
return;
|
||||
}
|
||||
if (!seat->current_constraint || pointer->base.type != WLR_INPUT_DEVICE_POINTER) {
|
||||
if (!seat->current_constraint
|
||||
|| pointer->base.type != WLR_INPUT_DEVICE_POINTER
|
||||
|| seat->current_constraint->type
|
||||
!= WLR_POINTER_CONSTRAINT_V1_CONFINED) {
|
||||
return;
|
||||
}
|
||||
assert(seat->current_constraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED);
|
||||
|
||||
double sx = seat->cursor->x;
|
||||
double sy = seat->cursor->y;
|
||||
|
|
@ -866,7 +868,9 @@ cursor_locked(struct seat *seat, struct wlr_pointer *pointer)
|
|||
{
|
||||
return seat->current_constraint
|
||||
&& pointer->base.type == WLR_INPUT_DEVICE_POINTER
|
||||
&& seat->current_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED;
|
||||
&& seat->current_constraint->type == WLR_POINTER_CONSTRAINT_V1_LOCKED
|
||||
&& seat->current_constraint->surface
|
||||
== seat->seat->pointer_state.focused_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -981,11 +985,6 @@ handle_motion_absolute(struct wl_listener *listener, void *data)
|
|||
double dx = lx - seat->cursor->x;
|
||||
double dy = ly - seat->cursor->y;
|
||||
|
||||
wlr_relative_pointer_manager_v1_send_relative_motion(
|
||||
seat->server->relative_pointer_manager,
|
||||
seat->seat, (uint64_t)event->time_msec * 1000,
|
||||
dx, dy, dx, dy);
|
||||
|
||||
preprocess_cursor_motion(seat, event->pointer,
|
||||
event->time_msec, dx, dy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ edge_from_cursor(struct seat *seat, struct output **dest_output,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (rc.snap_edge_range == 0) {
|
||||
if (rc.snap_edge_range_inner == 0 && rc.snap_edge_range_outer == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -197,9 +197,31 @@ edge_from_cursor(struct seat *seat, struct output **dest_output,
|
|||
}
|
||||
*dest_output = output;
|
||||
|
||||
/* Translate into output local coordinates */
|
||||
double cursor_x = seat->cursor->x;
|
||||
double cursor_y = seat->cursor->y;
|
||||
|
||||
int top_range = rc.snap_edge_range_outer;
|
||||
int bottom_range = rc.snap_edge_range_outer;
|
||||
int left_range = rc.snap_edge_range_outer;
|
||||
int right_range = rc.snap_edge_range_outer;
|
||||
if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_UP,
|
||||
output->wlr_output, cursor_x, cursor_y)) {
|
||||
top_range = rc.snap_edge_range_inner;
|
||||
}
|
||||
if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_DOWN,
|
||||
output->wlr_output, cursor_x, cursor_y)) {
|
||||
bottom_range = rc.snap_edge_range_inner;
|
||||
}
|
||||
if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_LEFT,
|
||||
output->wlr_output, cursor_x, cursor_y)) {
|
||||
left_range = rc.snap_edge_range_inner;
|
||||
}
|
||||
if (wlr_output_layout_adjacent_output(seat->server->output_layout, WLR_DIRECTION_RIGHT,
|
||||
output->wlr_output, cursor_x, cursor_y)) {
|
||||
right_range = rc.snap_edge_range_inner;
|
||||
}
|
||||
|
||||
/* Translate into output local coordinates */
|
||||
wlr_output_layout_output_coords(seat->server->output_layout,
|
||||
output->wlr_output, &cursor_x, &cursor_y);
|
||||
|
||||
|
|
@ -210,13 +232,13 @@ edge_from_cursor(struct seat *seat, struct output **dest_output,
|
|||
int left = cursor_x - area->x;
|
||||
int right = area->x + area->width - cursor_x;
|
||||
|
||||
if (top < rc.snap_edge_range) {
|
||||
if (top < top_range) {
|
||||
*edge1 = LAB_EDGE_TOP;
|
||||
} else if (bottom < rc.snap_edge_range) {
|
||||
} else if (bottom < bottom_range) {
|
||||
*edge1 = LAB_EDGE_BOTTOM;
|
||||
} else if (left < rc.snap_edge_range) {
|
||||
} else if (left < left_range) {
|
||||
*edge1 = LAB_EDGE_LEFT;
|
||||
} else if (right < rc.snap_edge_range) {
|
||||
} else if (right < right_range) {
|
||||
*edge1 = LAB_EDGE_RIGHT;
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1085,6 +1085,7 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data)
|
|||
CONNECT_SIGNAL(xdg_surface, xdg_toplevel_view, new_popup);
|
||||
|
||||
wl_list_insert(&server->views, &view->link);
|
||||
view->creation_id = server->next_view_creation_id++;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1036,6 +1036,7 @@ xwayland_view_create(struct server *server,
|
|||
CONNECT_SIGNAL(xsurface, xwayland_view, map_request);
|
||||
|
||||
wl_list_insert(&view->server->views, &view->link);
|
||||
view->creation_id = view->server->next_view_creation_id++;
|
||||
|
||||
if (xsurface->surface) {
|
||||
handle_associate(&xwayland_view->associate, NULL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue