bbidulock / icewm

A window manager designed for speed, usability, and consistency
Other
596 stars 99 forks source link

Allow specifying <empty>.<empty> in winoptions #180

Closed jidanni closed 6 years ago

jidanni commented 7 years ago

Let's say there is a window that we hate, but we don't want to kill. At least we can grab it with the mouse and move its tab to the very right, etc.

But this gets boring if necessary every session.

The window doesn't even have a title.

I am thinking maybe there should be a regex that if matches, keeps such windows always at the right, left, etc.

So in some preference file, once could write e.g., /^$/ {keep right;}

gijsbers commented 7 years ago

The closest thing would be a winoption. See the icewm-winoptions manual page.

Code7R commented 7 years ago

I though we have already a winopitons setting to push a windows to another workspace. Isn't this enough already?

gijsbers commented 7 years ago

Suppose we have that then someone remarks that some hated windows are more hated than others, so need to be pushed farther right. While other windows are actually loved a lot, so much so that they need to go leftmost. Then for some locales we need to switch right with left and ...

bbidulock commented 7 years ago

Why not just minimize the hated window?

jidanni commented 7 years ago
  1. I always only use one workspace, and those hated windows (ibus IME), even thought very small, need to be there so one can enter Chinese.
  2. Just need some way to give it some order via preferences.
  3. What is bothering me is they are showing up at odd places in the order of the tabs at the bottom of the screen. This order has already been engraved in my head. So I want the boring tabs to always go on the right, or maybe be "unlisted" from the row at the bottom of the screen.
jidanni commented 7 years ago

http://www.icewm.org/manual/icewm-14.html has

window_class.window_name.window_role.option: argument window_class.window_name.option: argument window_class.window_role.option: argument window_name.window_role.option: argument window_class.option: argument window_name.option: argument window_role.option: argument

all on one line. file:///usr/share/doc/icewm-common/html/icewm.html#_window_options looks better, but is all in one hard to read big file...

jidanni commented 7 years ago
Each window on the desktop has (should) class and name resources associated with it. Some more recent applications will also have a window role resource, though not all do. They can be determined using the xprop utility.

s/has (should)/(should) have/

jidanni commented 7 years ago

OK maybe I could use something from http://www.icewm.org/manual/icewm-14.html but I can't use xprop to find the details of that window, because xprop has no -all option, and I can't put the xprop target on that window and at the same time call xprop from the shell.

OK I did it!

$ sleep 22; xprop&
[1] 16129
11:32 ~$ _ICEWM_TRAY(CARDINAL) = 0
_WIN_LAYER(CARDINAL) = 4
_NET_WM_DESKTOP(CARDINAL) = 0
_WIN_WORKSPACE(CARDINAL) = 0
WM_STATE(WM_STATE):
                window state: Normal
                icon window: 0x0
_NET_WM_STATE(ATOM) = _NET_WM_STATE_FOCUSED
_WIN_STATE(CARDINAL) = 0, 1023
_NET_FRAME_EXTENTS(CARDINAL) = 4, 4, 24, 4
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _NET_WM_ACTION_STICK, _NET_WM_ACTION_CHANGE_DESKTOP
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW
[1]+  Done                    xprop

As we see, this is much less info that doing xprop on the shell window itself,

$ xprop
_ICEWM_TRAY(CARDINAL) = 0
_WIN_LAYER(CARDINAL) = 4
_NET_WM_DESKTOP(CARDINAL) = 0
_WIN_WORKSPACE(CARDINAL) = 0
WM_STATE(WM_STATE):
                window state: Normal
                icon window: 0x0
_NET_WM_STATE(ATOM) = _NET_WM_STATE_FOCUSED
_WIN_STATE(CARDINAL) = 0, 1023
_NET_FRAME_EXTENTS(CARDINAL) = 4, 4, 24, 4
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _NET_WM_ACTION_STICK, _NET_WM_ACTION_CHANGE_DESKTOP
_NET_WM_VISIBLE_ICON_NAME(UTF8_STRING) = "xterm"
_NET_WM_VISIBLE_NAME(UTF8_STRING) = "uxterm"
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW
_NET_WM_PID(CARDINAL) = 1090
WM_CLIENT_LEADER(WINDOW): window id # 0x100000f
WM_LOCALE_NAME(STRING) = "zh_TW.UTF-8"
WM_CLASS(STRING) = "xterm", "UXTerm"
WM_HINTS(WM_HINTS):
                Client accepts input or input focus: True
                Initial state is Normal State.
                bitmap id # to use for icon: 0x100001d
                bitmap id # of mask for icon: 0x100001f
WM_NORMAL_HINTS(WM_SIZE_HINTS):
                user specified size: 2017 by 2002
                program specified size: 2017 by 2002
                program specified minimum size: 28 by 22
                program specified resize increment: 9 by 18
                program specified base size: 19 by 4
                window gravity: NorthWest
WM_CLIENT_MACHINE(STRING) = "jidanni7"
WM_COMMAND(STRING) = { "xterm", "-class", "UXTerm", "-title", "uxterm", "-u8" }
WM_ICON_NAME(STRING) = "xterm"
WM_NAME(STRING) = "uxterm"

so maybe I am out of luck anyway.

bbidulock commented 7 years ago

There is no WM_CLASS on that window, not even a WM_NAME, so it cannot be identified.

gijsbers commented 7 years ago

If it would then one could use a feature option:

         ignoreTaskBar:            {1|0}  not on task bar.
jidanni commented 7 years ago

@bbidulock well here I have moved it close to its TaskBar block for a "group picture", so that proves parts of icewm do know about it (else how could I move it?). dd

bbidulock commented 7 years ago

What I meant was that because it doesn't have a WM_CLASS or WM_NAME you cannot refer to it in an IceWM configuration file (i.e. Ice can't find it next time it starts).

bbidulock commented 7 years ago

If you want to take it off the task bar, do

wmctrl -b add skip_taskbar :SELECT:

and then click on the window with the crosshairs.

Or, you can right click on its tab, got to window list, right click on the window and click "Hide". Then it will disappear from the task bar and window lists. You could normally do this in the winoptions file. So if its resource class and name was Stupid.stupid, you could add:

Stupid.stupid.ignoreTaskBar: 1
Stupid.stupid.ignoreWinList: 1
Stupid.stupid.geometry: -20-30

to your winoptions file and put it in the bottom right corner and remove it from the task bar and window list. See icewm-winoptions(5) manual page (if you have current git version).

I don't see what else needs to be done.

jidanni commented 7 years ago

Thanks but I don't want to manually have to do this every time I power up my computer. Maybe

''.''.ignoreTaskBar: 1
''.''.ignoreWinList: 1
''.''.geometry: -20-30

could be used but that might occasionally zap innocent windows...

jidanni commented 7 years ago

Here is how the no-name window exists in the process table:

$ pstree -al
  ├─ibus-daemon -drx
  │   ├─ibus-dconf
  │   │   └─3*[{ibus-dconf}]
  │   ├─ibus-engine-sim
  │   │   └─2*[{ibus-engine-sim}]
  │   ├─ibus-ui-gtk3
  │   │   └─3*[{ibus-ui-gtk3}]
  │   └─2*[{ibus-daemon}]
  ├─ibus-x11 --kill-daemon
  │   └─2*[{ibus-x11}]
gijsbers commented 7 years ago

wmctrl -l gives a list of managed windows. Your ibus program should be in it. This could be used to write a little script to set needed properties. Maybe other wmctrl options are helpful too to identify the ibus window, like -p. For each window xprop -id window shows the properties. Your window is identified with the output _NET_FRAME_EXTENTS(CARDINAL) = 4, 4, 24, 4. You could file an issue with them asking for basic ICCCM compliance.

jidanni commented 7 years ago

OK, while working on this I found some more errors...

$ wmctrl -p -l -G -v -x
envir_utf8: 1
Invalid type of WM_CLIENT_MACHINE property.
Invalid type of WM_NAME property.
Invalid type of _NET_WM_NAME property.
Invalid type of WM_CLASS property.
Invalid type of WM_CLIENT_MACHINE property.
Invalid type of _NET_WM_PID property.
0x00e0000f  0 0      4    24   48   24   N/A                        N/A N/A
Invalid type of _NET_WM_NAME property.
0x0120000f  0 16378  4    24   1675 994  xterm.UXTerm          jidanni7 uxterm
0x01000123  0 16379  0    20   1680 992  emacs.Emacs           jidanni7 E16:54macs
Invalid type of _NET_WM_NAME property.
0x0140000f  0 16410  4    24   1675 994  SU.UXTerm             jidanni7 SU
Invalid type of WM_NAME property.
0x01a00001  0 19075  0    20   1680 1004 chromium.Chromium     jidanni7 Comment Thread | Couchsurfing - Advice for Hosts | Groups | Couchsurfing - Chromium
jidanni commented 7 years ago

OK, getting warmer...

set -e -- $(wmctrl -p -l -G -x|perl -anwle 'next unless m!\s+0\s+0\s+4\s+24\s+48\s+24\s+N/A\s+N/A\s+N/A!; print $F[0];');\
test $@; xprop -id $@
_ICEWM_TRAY(CARDINAL) = 0
_WIN_LAYER(CARDINAL) = 4
_NET_WM_DESKTOP(CARDINAL) = 0
_WIN_WORKSPACE(CARDINAL) = 0
WM_STATE(WM_STATE):
        window state: Normal
        icon window: 0x0
_NET_WM_STATE(ATOM) = 
_WIN_STATE(CARDINAL) = 0, 1023
_NET_FRAME_EXTENTS(CARDINAL) = 4, 4, 24, 4
_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_CLOSE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_ABOVE, _NET_WM_ACTION_BELOW, _NET_WM_ACTION_STICK, _NET_WM_ACTION_CHANGE_DESKTOP
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW
jidanni commented 7 years ago

Alas, still not enough info to satisfy https://github.com/bbidulock/icewm/issues/180#issuecomment-336801973

set -e -- $(wmctrl -p -l -G -x|perl -anwle 'next unless m!\s+0\s+0\s+4\s+24\s+48\s+24\s+N/A\s+N/A\s+N/A!; print $F[0];');\
test $@; xprop -id $@ | egrep -c WM_CLASS\|WM_NAME
0

Hmm, so maybe _NET_FRAME_EXTENTS(CARDINAL) should be allowed in the icewm configuration file... (Actually this is getting rather out of hand, as then the configuration file will need to be generated by some wrapper script each time a little after starting icewm.)

I have a better idea, just have a setting where icewm could filter on .bla and . and bla. in in the winoptions file.

jidanni commented 7 years ago

Thought it might also zap more anonymous windows than was intended, that is their own fault for having no names.

bbidulock commented 7 years ago

Fix the client application. It is trivial to set WM_CLASS and WM_NAME.

jidanni commented 7 years ago

I am still waiting for the Ibus team to allow me to see fonts other than 10 points therefore assume the client application is unfixable please.

bbidulock commented 7 years ago

The WM_CLASS property (of type STRING without control characters) contains two consecutive null-terminated strings. These specify the Instance and Class names to be used by both the client and the window manager for lookup up resources for the application or as identifying information. This property must be present when the window leaves the Withdrawn state and may be changed only while the window is in the Withdrawn state.

That written in ICCCM 2.0 released April 1994. I am sorry, but I will not accommodate an application that can't even follow a 23-year old requirement.

jidanni commented 7 years ago

Yes but that is like as if Spamassassin only allowed one to filter mails confoming to all RFCs, where in reality non-conformance is one of the chief traits of spam, so the user wants a way to reject it, not accept it!!

fujiwarat commented 7 years ago

GtkStatusIcon sets WM_NAME and WM_ICON_NAME: https://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkwindow-x11.c#n2451

% gdb /usr/lib*/ibus-ui-gtk3
#0  0x00007ffff6f049d8 in gdk_x11_window_set_title (window=0x6c4660 [GdkX11Window], title=0x8b8510 "IBus パネル") at gdkwindow-x11.c:2819
#1  0x00007ffff6ecda78 in gdk_window_set_title (window=0x6c4660 [GdkX11Window], title=0x8b8510 "IBus パネル") at gdkwindow.c:10435
#2  0x00007ffff765bbc4 in gtk_window_set_title_internal (window=0x6f43d0 [GtkTrayIcon], title=0x7fffe42ad299 "IBus パネル", update_titlebar=1)
    at gtkwindow.c:2344
#3  0x00007ffff765bd11 in gtk_window_set_title (window=0x6f43d0 [GtkTrayIcon], title=0x7fffe42ad299 "IBus パネル") at gtkwindow.c:2373
#4  0x00007ffff7271878 in gtk_status_icon_set_title (status_icon=0x73ec30 [GtkStatusIcon], title=0x7fffe42ad299 "IBus パネル")
    at deprecated/gtkstatusicon.c:2770
#5  0x0000000000440935 in panel_init_status_icon (self=0x73a2b0 [Panel])
    at panel.c:1535
#6  0x000000000043e2cb in panel_construct (object_type=7429488, bus=0x6fe190 [IBusBus]) at panel.c:859
#7  0x000000000043e71f in panel_new (bus=0x6fe190 [IBusBus]) at panel.c:906
#8  0x000000000040f34b in application_bus_name_acquired_cb (self=0x695210, connection=0x6e9210 [GDBusConnection], sender_name=0x7fffd8005fe0 "org.freedesktop.DBus", object_path=0x7fffd8017b10 "/org/freedesktop/DBus", interface_name=0x7fffd8008ed0 "org.freedesktop.DBus", signal_name=0x7fffd8017b30 "NameAcquired", parameters=0x7fffd80180c0) at application.c:252
#9  0x000000000040ef38 in _application_bus_name_acquired_cb_gd_bus_signal_callba
ck (connection=0x6e9210 [GDBusConnection], sender_name=0x7fffd8005fe0 "org.freedesktop.DBus", object_path=0x7fffd8017b10 "/org/freedesktop/DBus", interface_name=0x7fffd8008ed0 "org.freedesktop.DBus", signal_name=0x7fffd8017b30 "NameAcquired", parameters=0x7fffd80180c0, self=0x695210) at application.c:190
#10 0x00007ffff5717974 in emit_signal_instance_in_idle_cb (data=data@entry=0x7fffd80186d0) at gdbusconnection.c:3705
#11 0x00007ffff513f8e7 in g_idle_dispatch (source=0x7fffd8018400, callback=0x7ffff5717900 <emit_signal_instance_in_idle_cb>, user_data=0x7fffd80186d0)
    at gmain.c:5545
#12 0x00007ffff5142e52 in g_main_dispatch (context=0x6d3a00) at gmain.c:3203
#13 0x00007ffff5142e52 in g_main_context_dispatch (context=context@entry=0x6d3a00) at gmain.c:3856
#14 0x00007ffff51431d0 in g_main_context_iterate (context=0x6d3a00, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3929
#15 0x00007ffff51434f2 in g_main_loop_run (loop=0x72f640) at gmain.c:4125
#16 0x00007ffff746461d in gtk_main () at gtkmain.c:1301
#17 0x000000000040f15e in application_run (self=0x695210) at application.c:223
#18 0x000000000040f839 in application_main (argv=0x7fffffffdee8, argv_length1=1) at application.c:328
#19 0x000000000040f877 in main (argc=1, argv=0x7fffffffdee8)
    at application.c:337

GtkStatusIcon is based on System Tray Protocol in freedesktop: https://specifications.freedesktop.org/systemtray-spec/systemtray-spec-0.3.html

IBus panel is expected to be embedded in the panel in your desktop but not an isolated window. This is an instance on XFCE desktop: ibus-panel-icon-on-systray

bbidulock commented 7 years ago

I suppose the question now is why the hated window is not being adopted by the tray. @jidanni are you running icewmtray before the application? If so, there can be several reasons: one could be that IceWM does not use XEMBED (it just reparents the window).

jidanni commented 7 years ago

All I know is sometimes it is embedded, sometimes not. In .xsession I do something like

export GTK_IM_MODULE=ibus XMODIFIERS=@im=ibus QT_IM_MODULE=ibus
ibus-daemon -drx
icewm-session &
sleep 5
wait
gijsbers commented 7 years ago

Could you try starting ibus much later like this:

icewm-session &
sleep 5
export GTK_IM_MODULE=ibus XMODIFIERS=@im=ibus QT_IM_MODULE=ibus
ibus-daemon -drx
wait
bbidulock commented 7 years ago

Try this latest commit c02457a and see if it fixes the problem.

jidanni commented 7 years ago

OK but I'll wait for the .deb.

jidanni commented 6 years ago

Lately the windows that bother me have gone away. So I don't have anything more to test. So OK I'll close it.