Since commit 102063dbbd, awesome is a reparenting WM. That means that we put our
own frame windows around child windows. This means that we have the option of
grabbing input events on the frame window or the child window. This commit chose
the frame window for this.
For keyboard events, this decision was already reverted in 532ec0cd90. This
commit does the same thing for mouse events.
This fixes the spurious leave/enter events that were visible on mouse clicks.
They occurred because the click activated a passive grab (all mouse events now
"belonged" to awesome). This passive grab caused the X server to inform clients
that they "lost" the mouse pointer (with the detail field set to "a grab
activated").
Fixes: https://github.com/awesomeWM/awesome/issues/427
Signed-off-by: Uli Schlachter <psychon@znc.in>
Instead of computing the workarea whenever some Lua code asks for it, it is now
remembered explicitly as a property on a screen. This allows us to only emit
property::workarea if the workarea actually changed.
Fixes: https://github.com/awesomeWM/awesome/issues/756
Signed-off-by: Uli Schlachter <psychon@znc.in>
Apparently the spec allows to set the _NET_STARTUP_ID value on the property that
WM_CLIENT_LEADER points to instead of the window itself. Thus, if we don't find
a _NET_STARTUP_ID on the window itself, check again on the client leader window.
Apparently GTK even does this (for whatever reason...)...
Signed-off-by: Uli Schlachter <psychon@znc.in>
When a screen is removed, we have to update screen.primary (if it was the
removed screen) and assign a different screen to all clients which were on the
removed screen.
Signed-off-by: Uli Schlachter <psychon@znc.in>
A client cannot be used any more after it was unmanaged. Similarly, Lua
shouldn't be allowed to e.g. assign a client to a screen that was removed. This
commit adds such a checker which "breaks" all screens which are not in the
global screen list.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit adds a "removed" signal to screens. Together with the "added" signal
that we have since a while, this allows the C code to update the list of
available screens dynamically without needing to restart.
So far, this code received only minimal testing. So far, I don't have a nice
idea on how to easily test this...
Closes: https://github.com/awesomeWM/awesome/issues/672
Signed-off-by: Uli Schlachter <psychon@znc.in>
We once had the problem that with the nvidia blob, the X11 server told us that
"yes, I do support RandR; there is just a single big screen" even though there
were multiple screens and they could be queried for via Xinerama. To work around
this, we started to ignore RandR if it only provided information about a single
screen.
Our long-term goal is to stop restarting on RandR screen changes. Thus, even if
only a single screen is defined during startup, we should still use RandR later
when another screen is added. This means that we cannot just ignore RandR if it
only mentions a single screen.
This commit copies what GTK+ does: If there is an output named "default", then
some compatibility layer is assumed and we ignore RandR.
I have no way to test if this really does the right thing.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Instead of adding all screens directly to globalconf.screens, the individual
"scanner functions" now get a screen_array_t as their argument and add the
screens there. Also, they no longer emit the "added" signal themselves (through
screen_add()), but the caller does now does this instead once all screens are
found.
This commit drops the "deduplication" of screens. This likely means that clone
mode causes duplicate screens. This will have to be re-added later.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Remove request::fullscreen and request::maximized_* and use
a single request for them. The other client resizing features
will soon also start to use this.
In the case where one want to put the cursor at the middle of the
workarea, it is logic to do:
x=screen.workarea.x+screen.workasrea.width/2
However, this can cause floating points. This commit move the
burden back to the C-API so the Lua placement code doesn't have
to add a large number of rounding methods. Given 1 type of rounding
cover a vast majority of use cases for each types of coordinates,
the C-API can take care of it in peace. For the other corner cases,
it is still possible for the Lua code to do the rounding there, but
no longer necessary. The convenstions are:
'x' and 'y': use round (move to the closest point)
'width' and 'height': use ceil (to avoid involontary truncating)
This change catches things like c:geometry { width = -42 }.
Helps-a-bit-with: https://github.com/awesomeWM/awesome/pull/820 (fixes X errors)
Signed-off-by: Uli Schlachter <psychon@znc.in>
Commit c543f59696 introduced the following warnings:
objects/screen.c:307:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
objects/screen.c:307:1: warning: no previous prototype for ‘screen_scan_randr_monitors’ [-Wmissing-prototypes]
Signed-off-by: Uli Schlachter <psychon@znc.in>
XRandR 1.5 adds support for the new monitor objects.
'Monitor' is a rectangular subset of the screen which represents a
coherent collection of pixels presented to the user. Each Monitor is be
associated with a list of outputs (which may be empty).
The patch below matches 1:1 screens in AwesomeWM with XRandR's Monitors.
This way I get one screen across my 4K monitor, which is represented by
two CRTCs.
Background info: http://keithp.com/blogs/MST-monitors/
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
This commit makes all C code that previously returned a screen index now return
a screen object, continuing the deprecation of screen indicies. Note that this
is an API break and will likely cause all kinds of problems for users.
The change also breaks some tests which are suitably fixed in this commit.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Instead of focusing the root window, we now create a "focus window" inside of
our frame window. This window is placed so that it is not visible, but we can
grab key bindings on it to simulate the window having the input focus.
Fixes: https://github.com/awesomeWM/awesome/issues/699
Signed-off-by: Uli Schlachter <psychon@znc.in>
Right now this just always returns the first screens, but this can easily be
implemented properly later.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Even when a screen is just an integer, the code becomes a bit more
self-documenting. Even better, if we start to handle screen objects to Lua
instead of screen indicies, there will only be one place that needs to be
changed.
Signed-off-by: Uli Schlachter <psychon@znc.in>
When we manage the transient before the main window, the client object's
.transient_for property would stay nil. This happens because the property points
to a window which we don't know (yet) and thus is ignored.
Fix this by remembering the value of WM_TRANSIENT_FOR and checking in
client_manage() if the new client is the "missing window we did not find
before".
Fixes: https://github.com/awesomeWM/awesome/issues/181
Signed-off-by: Uli Schlachter <psychon@znc.in>
This creates a new helper function for setting the transient_for property of a
client. This is a preparation for a following commit. No behaviour changes
intended.
Signed-off-by: Uli Schlachter <psychon@znc.in>
To quote from ICCCM (§4.1.2): "The window manager will not change properties
written by the client."
We tried to do this anyway to update WM_HINTS so that the current urgency state
is reflected. Apparently, Chrome does a similar read-modify-set cycle and the
resulting race condition meant that the "accepts input" hint on Chromium's
window was permanently disabled.
This helps with https://github.com/awesomeWM/awesome/issues/670, but I still
think that Chrome shouldn't try to implement "please don't focus me when I do
the following" by temporarily claiming "please don't ever focus me".
Signed-off-by: Uli Schlachter <psychon@znc.in>
E.g. trying to press mouse button 1.5 via root.fake_input() doesn't make sense.
Previously the code silently truncated the number to an integer. Now it
complains about this instead.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The only remaining calls are for a window's opacity and in the DBus type
handling. Everything else wants integers, not something with a comma.
Signed-off-by: Uli Schlachter <psychon@znc.in>
ICCCM specifies when the WM has to send a ConfigureNotify. Java does not care
and wants one all the time. Meh.
Fixes: #248
Signed-off-by: Uli Schlachter <psychon@znc.in>
This allow layout "arrange" to be called less often and react on
the cause of the change itself rather than it's consequences
(usually, the "focus" signal).
Previously, the layout were re-arranged everytime the focus changed.
Now, with "raised" and "lowered", it require less "arrange".
"swapped" allow smarted layouts. Currently, swapped cause a full
re-arrange. It re-read the "index" list from scratch and create
a "new" layout. With "swapped", incremental layout changes are
possible.
Fixes https://github.com/awesomeWM/awesome/issues/616
When a client is unmanaged, we know emit mouse::leave on its titlebar before the
client object is invalidated, so that Lua can still work with it. Before, this
event was emitted only when we got a LeaveNotify from the X11 server.
Fixes: #620
Signed-off-by: Uli Schlachter <psychon@znc.in>
luaA_warn() prints a Lua backtrace and thus generates more useful output. warn()
should only be used in awesome-internal places (e.g. receiving an error from the
X11 server).
Closes https://github.com/awesomeWM/awesome/pull/608.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Some words about X11 event handling: Every X11 client can select input on any
window. For this, inside the X11 server each window has for each client a
bitmask for the kind of events that this client is interested in. When a mouse
button is pressed inside of a window, a corresponding event is generated for
that window and sent to all X11 clients which asked for
XCB_EVENT_MASK_BUTTON_PRESS. When no client is interested in this event, the
event is propagated to the parent window and the same procedure is done again
here. This continues up until the root window is reached.
Some words about the event masks that awesome uses: For clients, we ask for
button press events on the frame window that we reparent the client window into
so that we get any kind of press on the titlebar (and also events inside of the
client window if the client itself doesn't care for click events?). We are also
interested in button presses / releases on the root window. However, before this
commit, we didn't actually ask for button events on drawins (e.g. the wibox).
This worked fine, because no one asked for these events and the event propagated
to the root window where it was then sent to awesome.
However, newer Qt versions do something weird and the above broke. I don't
actually know what is going on. I know about the above propagation rules, but
looking at protocol traces of what Qt does, awesome should still get the button
events. During startup, Qt asks for button events on its own windows. After a
hotplug event, it asks the same again, but now also includes the root window.
So... how can Qt asking for button events on the root window cause awesome not
to get them? I have no idea.
(And yes, I guess that Qt asking for mouse events on the root window is a bug,
but I have no idea how exactly this happens nor about any other side effects of
it).
This commit makes us ask for button events on our drawins so that the server
will send them to us. This is the right thing to do anyway and it was reported
to have some positive effects.
Ref: https://github.com/awesomeWM/awesome/issues/415
Signed-off-by: Uli Schlachter <psychon@znc.in>
The only exception is the window for _NET_SUPPORTING_WM_CHECK. That window
already had a _NET_WM_NAME property before and doesn't get a WM_NAME property in
this commit. I just decided for myself that it doesn't need one. :-)
Right after startup with the default config we now have the following situation:
$ xwininfo -root -tree
xwininfo: Window id: 0x2d7 (the root window) (has no name)
Root window id: 0x2d7 (the root window) (has no name)
Parent window id: 0x0 (none)
7 children:
0x200011 "Awesome drawin": ("awesome" "awesome") 1500x20+0+0 +0+0
0x200010 "Awesome drawin": ("awesome" "awesome") 1x1+0+0 +0+0
0x20000d "Awesome drawin": ("awesome" "awesome") 100x30+0+0 +0+0
0x20000a "Awesome no input window": ("awesome" "awesome") 1x1+-1+-1 +-1+-1
0x200009 "Awesome systray window": ("awesome" "awesome") 1x1+-1+-1 +-1+-1
0x200008 "awesome": ("awesome" "awesome") 1x1+-1+-1 +-1+-1
0x200007 "Awesome WM_Sn selection owner window": ("awesome" "awesome") 1x1+-1+-1 +-1+-1
One of those drawin is the awful.wibox. Another drawin is created by awful.menu.
I guess that the third one is created by awful.tooltip, but I'm not sure. Wow,
so many windows...
Closes https://github.com/awesomeWM/awesome/pull/556.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This is an enhancement to make non-ASCII symbol keys usable for
implementation and configuration of Awesome.
The enhancement was proposed and had been developed under the
initiative of Daniel Hahler. Thanks to his sharing of his results with our
community, we gradually deepened our understanding on the issue. This
commit is the fruit his enthusiasm spawned.
Closes https://github.com/awesomeWM/awesome/pull/538.
Before this, we grabbed the keys on the frame window. That meant we only got key
events for things that nothing else grabbed directly on the key window.
After this, we grab directly on the client window itself and so we "fight" with
everything else which wants to grab keys. I don't actually know how the winner
is decided... First come, first serve, the rest gets an error?
Signed-off-by: Uli Schlachter <psychon@znc.in>
The bit that indicates that the base size is set is
XCB_ICCCM_SIZE_HINT_BASE_SIZE. However, instead this code checked
XCB_ICCCM_SIZE_HINT_P_SIZE which is set to indicate how the initial window
position is chosen. So we were checking the complete wrong bit. Whoops...
Fixes: https://github.com/awesomeWM/awesome/issues/456
Signed-off-by: Uli Schlachter <psychon@znc.in>
Instead of comparing only the top-left corner of the screen to the provided
coordinate, this now compares the screen in a more intuitive way, e.g.
coordinates inside of the screen have a distance of zero.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Together with the previous changes, this also fixes the initial positions for
metacity's test-gravity.c.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Whenever client.focus == nil, we set the input focus to the root window to
express "nothing has the input focus". However, thanks to the way X11 input
works, this means that whatever is under the mouse cursor gets keyboard input
events. This can easily be reproduced with urxvt and some small addition to the
config to unfocus things.
This commit changes things. Instead of focusing the root window, we create a
special "no focus" window that gets focused if we want nothing to have the
focus.
Closes https://github.com/awesomeWM/awesome/pull/470.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This makes it possible to add something similar to a __index / __newindex
metamethod to all our C objects. Based on this, Lua can then easily implement
arbitrary properties on our capi objects.
From http://standards.freedesktop.org/wm-spec/latest/ar01s05.html:
> _NET_WM_STATE_FULLSCREEN indicates that the window should fill the
> entire screen and have no window decorations. Additionally the Window
> Manager is responsible for restoring the original geometry after a
> switch from fullscreen back to normal window. For example, a
> presentation program would use this hint.
awesome prefers fullscreen internally already. With this patch, the
previous maximized state will be restored after leaving fullscreen mode.
Fixes https://github.com/awesomeWM/awesome/issues/245.
Closes https://github.com/awesomeWM/awesome/pull/418.
This adds luaA_getopt_integer, luaA_optinteger and luaA_checkinteger.
Lua 5.2 does not have support for this, but it would be available in Lua
5.3.
Closes https://github.com/awesomeWM/awesome/pull/320.
This will skip calling `client_resize_do` in case of honored size hints.
This could be also done in `client_resize_do`, but it appears to be
meant to force the resize.
Closes https://github.com/awesomeWM/awesome/pull/383.
While debugging #331, I have noticed that the call to `client_resize`
might have changed the screen (and emitted the signal) already, via
a call to `screen_client_moveto` with `doresize=False`.
Closes https://github.com/awesomeWM/awesome/pull/332.
Instead of `client.client`, the client object is now referred to as
`client.object` and the client class as `client.class`.
This moves the documentation of `client.focus` to the class.
Closes https://github.com/awesomeWM/awesome/pull/349.
Calling lua_tostring() on a number/integer, turns that stack slot into a string.
This patch changes the code to only call lua_tostring() if the function argument
really is a string.
This partly also caused https://github.com/awesomeWM/awesome/issues/238.
Signed-off-by: Uli Schlachter <psychon@znc.in>
When minimizing a client, we temporarily ignore events for the client window (so
that we don't get the UnmapNotify event that we are causing for the unmap) and
for the root window (I don't actually know why, no "harmful" events should be
caused...).
However, we weren't ignoring events on the frame window itself. This commit
fixes that oversight.
The problem here is that the pointer could be inside the window that is being
minimized. When we then unmap said window, the pointer will now be inside of the
frame window and the X11 server will thus generate an EnterNotify. When we
handle this event later on, we emit mouse::enter on the client and e.g. the
default config then focuses this client, which undoes the minimization.
This fixes a regression introduced in commit 3aeac3870c and fixes#92.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This function gets a width and height of a client, applies the client's size
hints to these numbers and returns the result.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This fix two things:
(1) Clients asking to be urgent while focussed, this have been reported
a few time for urxvt and I usually link a patch that fix this. This may
not be considered a bug by some, but I think it is.
(2) Add the ability to stop noisy clients from setting the urgent state
themselves.
Because ICCCM pretty much mandates that minimized (aka "iconic") clients are
unmapped. In detail: To go back to normal state, the client should map its
window and for this to work, the window needs to be unmapped.
Thanks to Oleg Shparber for reporting some issue he had with a self-written Qt
program and for providing a simple and short test case.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Fun fact: ICCCM specifies that icon_pixmap must have depth 1. Xterm uses a
pixmap with depth 24. Yay... As such, I don't have any test for the depth == 1
case and will just assume that it does the right thing. If it doesn't, I bet no
one will notice anyway.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Everything that needs the lua_State should create a local variable like this:
lua_State *L = globalconf_get_lua_State();
This ensures that the compiler warns if there are two variables with name "L" in
scope. The idea here is that it should become harder to accidentally use the
global lua state instead of the state of the current state.
While writing this commit, I found another place that gets its wrong: Reading
client.focus from a coroutine was broken, since it was returning the result on
the main thread instead of the current one.
Signed-off-by: Uli Schlachter <psychon@znc.in>
tag_client() said that it refers to the tag ontop of the lua stack. However, it
implicitly used globalconf.L as its stack. So if you tagged a client with a tag
from a coroutine, thinks would Go Wrong (tm). Fix this by adding an explicit
lua_State* argument.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This just pushed the drawin onto the stack L, but then tries to access it via
globalconf.L. This just calls for problems...
Signed-off-by: Uli Schlachter <psychon@znc.in>
A stack index without the corresponding lua_State pointer is useless, because it
could reference another coroutine than the main thread and thus just assuming
globalconf.L is wrong. Fix this by also passing around the corresponding
lua_State pointer.
This improves the result for the following test:
coroutine.resume(coroutine.create(function()
drawin({}).visible = true
end))
Signed-off-by: Uli Schlachter <psychon@znc.in>
This fixes the following code:
local d = drawin({})
d.visible = true
The drawin now has a cairo surface assigned
d.visible = false
d.width = 1234
d.visible = true
The width change while the drawin was not visible would not get propagated to
the drawable because of the code that this patch removes. The expectation was
that drawin_map() would update the drawable later.
However, because the drawin was already visible, its drawable also already has
a surface assigned. Thus, drawin_map() wouldn't update the drawable either.
Fix this by just removing this optimizations.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The code in drawin_moveresize() tries to be clever and only updates the drawing
state of the drawable when it is resized, not when it is moved around. This used
to be necessary because once upon a time, drawin_update_drawing() threw away all
of the drawing state and thus forcing a repaint. These days it just calls
drawable_set_geometry() as well and that function special-cases moves.
So this old code in drawin_moveresize() is no longer necessary and actually
caused problems.
These problems occurred because drawin_update_drawing() is being clever and
doesn't do anything for .visible = false drawins, because their drawing state
will be updated once they become visible. However, not skipping
drawable_set_geometry() means that this broke, because drawin_map() thought that
the drawing state was up to date while in reality it wasn't.
References: http://article.gmane.org/gmane.comp.window-managers.awesome/10852
Signed-off-by: Uli Schlachter <psychon@znc.in>
The screen_output_t* that is passed to screen_output_wipe() points into the
middle of the output array table and is a pointer that we never allocated.
Instead, what we want to free here is the name of the output.
Thanks to luzie for reporting this.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Every .c file has to include the corresponding .h file first to make sure the
headers are self-contained. Additionally, this moves some unneeded includes
around.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The only caller for drawin_unref_simplified() is in ARRAY_FUNCS() and here it is
only used in the implementation of drawin_array_wipe(). However, this function
is unused and thus we don't need drawin_unref_simplified() either.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This makes the screen objects use our existing infrastructure for implementing
classes and objects with lua instead of hand-rolling an own version.
This results in some small API change: Screen objects no longer have an
add_signal() function and instead this function exists on the parent screen
class.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Previously we would get a short black flicker when a client closes. This
happened because first the client's window would get hidden and only a short
moment later would awesome react to this and close its own window. In the mean
time, the X server filled the frame window with its background-pixel which was
black.
Just removing the background-pixel means we get the default value which is None.
This means that the content will be left untouched and the client's window will
be visible for a moment longer.
Signed-off-by: Uli Schlachter <psychon@znc.in>
The X11 server tells us about things that need to be redrawn via expose events.
When we get such an expose event before lua drew the drawable, we just fill the
exposed area with old data (which is black for newly-created drawables).
Fix this by tracking if we have any usable data in a drawable's double buffering
pixmap. This flag is unset whenever we throw away the old content (e.g. due to a
resize) and is set when lua gave us some new content to display.
Signed-off-by: Uli Schlachter <psychon@znc.in>
We now handle all "important" EWMH messages in lua and lua can decide to do
different things than the current obvious one.
Consistency!
Signed-off-by: Uli Schlachter <psychon@znc.in>
Previously, ownership of the pixmaps that we are using for double buffering was
a little weird. The pixmap belonged to the drawin/titlebar, but the
corresponding cairo surface was owned by the drawable. Clean this up by moving
the pixmap to the drawable.
This cleans up lots of ugly code and also fixes a crash: When a drawable was
garbage collected before its drawin, drawin_wipe() would crash accessing the
drawable. This was needed to make it forget about the cairo surface we gave to
it for the pixmap that is being destroyed.
By moving the pixmap to the drawable, this whole issues goes away.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Whenever a titlebar of a client needed to be refreshed, all (possibly) four
titlebars would get completely refreshed. So if someone actually added more than
one titlebar to a client, awesome would copy each titlebar's content to the
window four times. Fix this by introducing more fine-grined functions for
uploads.
This also makes awesome only update the affected area when it gets an expose
event for a titlebar instead of all four titlebars completely.
Signed-off-by: Uli Schlachter <psychon@znc.in>
Before this commit, we always threw away the drawin's cairo surface whenever it
was made visible and thus forced a redraw.
This commit changes this so that we only force a redraw if the drawin was
resized why it wasn't visible. To remember when this happens, we free the
drawin's cairo surface without allocating a new one when the drawin is resized
while not being visible. Thus, we then only have to allocate a new surface if
the drawin doesn't have one when it is being made visible.
Signed-off-by: Uli Schlachter <psychon@znc.in>
This allow to spawn something, then apply some properties or rules when
the client show up ("manage").
This commit add:
* "startup_id" property for all clients object (immutable, can be nil)
* Second return value to awful.util.spawn() with the startup_id
* Update the documentation
Example:
local wait_for_it = {}
local pid,snid = awful.util.spawn("urxvtc")
wait_for_it[snid] = {ontop=true,sticky=false,
tag = awful.tag.gettags(mouse.screen)[1] }
client.connect_signal("manage", function (c, startup)
if c.startup_id and wait_for_it[c.startup_id] then
for k,v in pairs(wait_for_it[c.startup_id]) do
c[k] = v
end
if wait_for_it[c.startup_id].tag then
c:tags({wait_for_it[c.startup_id].tag})
end
end
end)
Signed-off-by: Uli Schlachter <psychon@znc.in>