Merge pull request #2982 from Elv13/modeline
Support shebangs (#!), modelines, API levels and add more doc.
This commit is contained in:
commit
10e32198e7
|
@ -69,6 +69,7 @@ set(AWE_SRCS
|
|||
${BUILD_DIR}/strut.c
|
||||
${BUILD_DIR}/systray.c
|
||||
${BUILD_DIR}/xwindow.c
|
||||
${BUILD_DIR}/options.c
|
||||
${BUILD_DIR}/xkb.c
|
||||
${BUILD_DIR}/xrdb.c
|
||||
${BUILD_DIR}/common/atoms.c
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#define AWESOME_VERSION "@AWESOME_VERSION@"
|
||||
#define AWESOME_RELEASE "@AWESOME_RELEASE@"
|
||||
#define AWESOME_API_LEVEL @AWESOME_API_LEVEL@
|
||||
|
||||
#endif //_AWE_VERSION_INTERNAL_H_
|
||||
|
||||
|
|
103
awesome.c
103
awesome.c
|
@ -36,6 +36,7 @@
|
|||
#include "spawn.h"
|
||||
#include "systray.h"
|
||||
#include "xwindow.h"
|
||||
#include "options.h"
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
|
@ -552,26 +553,6 @@ true_config_callback(const char *unused)
|
|||
return true;
|
||||
}
|
||||
|
||||
/** Print help and exit(2) with given exit_code.
|
||||
* \param exit_code The exit code.
|
||||
*/
|
||||
static void __attribute__ ((noreturn))
|
||||
exit_help(int exit_code)
|
||||
{
|
||||
FILE *outfile = (exit_code == EXIT_SUCCESS) ? stdout : stderr;
|
||||
fprintf(outfile,
|
||||
"Usage: awesome [OPTION]\n\
|
||||
-h, --help show help\n\
|
||||
-v, --version show version\n\
|
||||
-c, --config FILE configuration file to use\n\
|
||||
--search DIR add a directory to the library search path\n\
|
||||
-k, --check check configuration file syntax\n\
|
||||
-a, --no-argb disable client transparency support\n\
|
||||
-m, --screen on|off enable or disable automatic screen creation (default: on)\n\
|
||||
-r, --replace replace an existing window manager\n");
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
/** Hello, this is main.
|
||||
* \param argc Who knows.
|
||||
* \param argv Who knows.
|
||||
|
@ -580,27 +561,15 @@ exit_help(int exit_code)
|
|||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *confpath = NULL;
|
||||
string_array_t searchpath;
|
||||
int xfd, opt;
|
||||
int xfd;
|
||||
xdgHandle xdg;
|
||||
bool no_argb = false;
|
||||
bool run_test = false;
|
||||
bool replace_wm = false;
|
||||
xcb_query_tree_cookie_t tree_c;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'v' },
|
||||
{ "config", 1, NULL, 'c' },
|
||||
{ "check", 0, NULL, 'k' },
|
||||
{ "search", 1, NULL, 's' },
|
||||
{ "no-argb", 0, NULL, 'a' },
|
||||
{ "replace", 0, NULL, 'r' },
|
||||
{ "screen" , 1, NULL, 'm' },
|
||||
{ "reap", 1, NULL, '\1' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
/* The default values for the init flags */
|
||||
int default_init_flags = INIT_FLAG_NONE
|
||||
| INIT_FLAG_ARGB
|
||||
| INIT_FLAG_AUTO_SCREEN;
|
||||
|
||||
/* Make stdout/stderr line buffered. */
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
@ -611,6 +580,7 @@ main(int argc, char **argv)
|
|||
globalconf.keygrabber = LUA_REFNIL;
|
||||
globalconf.mousegrabber = LUA_REFNIL;
|
||||
globalconf.exit_code = EXIT_SUCCESS;
|
||||
globalconf.api_level = awesome_default_api_level();
|
||||
buffer_init(&globalconf.startup_errors);
|
||||
string_array_init(&searchpath);
|
||||
|
||||
|
@ -620,49 +590,11 @@ main(int argc, char **argv)
|
|||
/* Text won't be printed correctly otherwise */
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
/* check args */
|
||||
while((opt = getopt_long(argc, argv, "vhkc:arm:",
|
||||
long_options, NULL)) != -1)
|
||||
switch(opt)
|
||||
{
|
||||
case 'v':
|
||||
eprint_version();
|
||||
break;
|
||||
case 'h':
|
||||
exit_help(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'k':
|
||||
run_test = true;
|
||||
break;
|
||||
case 'c':
|
||||
if (confpath != NULL)
|
||||
fatal("--config may only be specified once");
|
||||
confpath = a_strdup(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
/* Validation */
|
||||
if ((!optarg) || !(A_STREQ(optarg, "off") || A_STREQ(optarg, "on")))
|
||||
fatal("The possible values of -m/--screen are \"on\" or \"off\"");
|
||||
char *confpath = options_detect_shebang(argc, argv);
|
||||
|
||||
globalconf.no_auto_screen = A_STREQ(optarg, "off");
|
||||
|
||||
break;
|
||||
case 's':
|
||||
string_array_append(&searchpath, a_strdup(optarg));
|
||||
break;
|
||||
case 'a':
|
||||
no_argb = true;
|
||||
break;
|
||||
case 'r':
|
||||
replace_wm = true;
|
||||
break;
|
||||
case '\1':
|
||||
/* Silently ignore --reap and its argument */
|
||||
break;
|
||||
default:
|
||||
exit_help(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
/* if no shebang is detected, check the args. Shebang (#!) args are parsed later */
|
||||
if (!confpath)
|
||||
confpath = options_check_args(argc, argv, &default_init_flags, &searchpath);
|
||||
|
||||
/* Get XDG basedir data */
|
||||
if(!xdgInitHandle(&xdg))
|
||||
|
@ -681,7 +613,8 @@ main(int argc, char **argv)
|
|||
string_array_append(&searchpath, entry);
|
||||
}
|
||||
|
||||
if (run_test)
|
||||
/* Check the configfile syntax and exit */
|
||||
if (default_init_flags & INIT_FLAG_RUN_TEST)
|
||||
{
|
||||
bool success = true;
|
||||
/* Get the first config that will be tried */
|
||||
|
@ -710,6 +643,10 @@ main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* Parse `rc.lua` to see if it has an AwesomeWM modeline */
|
||||
if (!(default_init_flags & INIT_FLAG_FORCE_CMD_ARGS))
|
||||
options_init_config(awesome_argv[0], confpath, &default_init_flags, &searchpath);
|
||||
|
||||
/* Setup pipe for SIGCHLD processing */
|
||||
{
|
||||
if (!g_unix_open_pipe(sigchld_pipe, FD_CLOEXEC, NULL))
|
||||
|
@ -751,7 +688,7 @@ main(int argc, char **argv)
|
|||
|
||||
globalconf.screen = xcb_aux_get_screen(globalconf.connection, globalconf.default_screen);
|
||||
globalconf.default_visual = draw_default_visual(globalconf.screen);
|
||||
if(!no_argb)
|
||||
if(default_init_flags & INIT_FLAG_ARGB)
|
||||
globalconf.visual = draw_argb_visual(globalconf.screen);
|
||||
if(!globalconf.visual)
|
||||
globalconf.visual = globalconf.default_visual;
|
||||
|
@ -794,7 +731,7 @@ main(int argc, char **argv)
|
|||
draw_test_cairo_xcb();
|
||||
|
||||
/* Acquire the WM_Sn selection */
|
||||
acquire_WM_Sn(replace_wm);
|
||||
acquire_WM_Sn(default_init_flags & INIT_FLAG_REPLACE_WM);
|
||||
|
||||
/* initialize dbus */
|
||||
a_dbus_init();
|
||||
|
|
|
@ -271,6 +271,7 @@ else()
|
|||
set(AWESOME_MAN_PATH ${CMAKE_INSTALL_PREFIX}/share/man CACHE PATH "awesome manpage directory")
|
||||
endif()
|
||||
|
||||
|
||||
# Hide to avoid confusion
|
||||
mark_as_advanced(CMAKE_INSTALL_CMAKE_INSTALL_PREFIX)
|
||||
|
||||
|
@ -280,6 +281,7 @@ set(AWESOME_SYSCONFDIR ${XDG_CONFIG_DIR}/${PROJECT_AWE_NAME})
|
|||
set(AWESOME_LUA_LIB_PATH ${AWESOME_DATA_PATH}/lib)
|
||||
set(AWESOME_ICON_PATH ${AWESOME_DATA_PATH}/icons)
|
||||
set(AWESOME_THEMES_PATH ${AWESOME_DATA_PATH}/themes)
|
||||
set(AWESOME_API_LEVEL 4)
|
||||
# }}}
|
||||
|
||||
if(GENERATE_DOC)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
-- awesome_mode: api-level=4:screen=on
|
||||
-- If LuaRocks is installed, make sure that packages installed through it are
|
||||
-- found (e.g. lgi). If LuaRocks is not installed, do nothing.
|
||||
pcall(require, "luarocks.loader")
|
||||
|
@ -537,3 +538,8 @@ client.connect_signal("request::titlebars", function(c)
|
|||
}
|
||||
end)
|
||||
-- }}}
|
||||
|
||||
-- Enable sloppy focus, so that focus follows mouse.
|
||||
client.connect_signal("mouse::enter", function(c)
|
||||
c:activate { context = "mouse_enter", raise = false }
|
||||
end)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "common/version.h"
|
||||
#include "globalconf.h"
|
||||
#include "awesome-version-internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -67,16 +68,28 @@ eprint_version(void)
|
|||
|
||||
printf("awesome %s (%s)\n"
|
||||
" • Compiled against %s (running with %s)\n"
|
||||
" • API level: %d\n"
|
||||
" • D-Bus support: %s\n"
|
||||
" • xcb-errors support: %s\n"
|
||||
" • execinfo support: %s\n"
|
||||
" • xcb-randr version: %d.%d\n"
|
||||
" • LGI version: %s\n",
|
||||
AWESOME_VERSION, AWESOME_RELEASE,
|
||||
LUA_RELEASE, lua_tostring(L, -2),
|
||||
has_dbus, has_xcb_errors, has_execinfo,
|
||||
XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION,
|
||||
lua_tostring(L, -1));
|
||||
" • LGI version: %s\n"
|
||||
" • Transparency enabled: %s\n"
|
||||
" • Custom search paths: %s\n",
|
||||
/* version */ AWESOME_VERSION,
|
||||
/* release */ AWESOME_RELEASE,
|
||||
/* Lua linked */ LUA_RELEASE,
|
||||
/* Lua runtime */ lua_tostring(L, -2),
|
||||
/* API Level */ globalconf.api_level,
|
||||
/* DBus */ has_dbus,
|
||||
/* XCB Error */ has_xcb_errors,
|
||||
/* Execinfo */ has_execinfo,
|
||||
/* XRandR major */ XCB_RANDR_MAJOR_VERSION,
|
||||
/* XRandR minor */ XCB_RANDR_MINOR_VERSION,
|
||||
/* LGI version */ lua_tostring(L, -1),
|
||||
/* ARGB support */ globalconf.had_overriden_depth ? "no" : "yes",
|
||||
/* Search path */ globalconf.have_searchpaths ? "yes" : "no"
|
||||
);
|
||||
lua_close(L);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
|
@ -100,4 +113,11 @@ awesome_release_string(void)
|
|||
return AWESOME_RELEASE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
awesome_default_api_level(void)
|
||||
{
|
||||
return AWESOME_API_LEVEL;
|
||||
}
|
||||
|
||||
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
void eprint_version(void) __attribute__ ((noreturn));
|
||||
const char *awesome_version_string(void);
|
||||
const char *awesome_release_string(void);
|
||||
int awesome_default_api_level(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,279 @@
|
|||
# Startup options
|
||||
|
||||
This document explains how to control how AwesomeWM behaves before `rc.lua` is
|
||||
executed.
|
||||
|
||||
## Command line
|
||||
|
||||
AwesomeWM has the following command line options:
|
||||
|
||||
Usage: awesome [OPTION]
|
||||
-h, --help show help
|
||||
-v, --version show version
|
||||
-c, --config FILE configuration file to use
|
||||
-f --force ignore modelines and apply the command line arguments
|
||||
-s, --search DIR add a directory to the library search path
|
||||
-k, --check check configuration file syntax
|
||||
-a, --no-argb disable client transparency support
|
||||
-l --api-level LEVEL select a different API support level than the current version
|
||||
-m, --screen on|off enable or disable automatic screen creation (default: on)
|
||||
-r, --replace replace an existing window manager
|
||||
|
||||
## Modelines
|
||||
|
||||
Usually, AwesomeWM is started using a session manager rather than directly using
|
||||
the command line. On top of that, to make `rc.lua` more portable, it is possible
|
||||
to set many of those options directly in your config file. They will be
|
||||
interpreted before the Lua virtual machine is started. The keys are:
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Name</th>
|
||||
<th align='center'>Has argument</th>
|
||||
<th align='center'>Allow many</th>
|
||||
<th align='center'>Type</th>
|
||||
<th align='center'>Description</th>
|
||||
</tr>
|
||||
<tr><td>search</td><td>Yes</td><td>Yes</td><td>string</td><td>Path where the AwesomeWM core libraries are located</td></tr>
|
||||
<tr><td>no-argb</td><td>No</td><td>No</td><td>N/A</td><td>Disable built-in (real) transparency.</td></tr>
|
||||
<tr><td>api-level</td><td>Yes</td><td>No</td><td>integer</td><td>The config API level.</td></tr>
|
||||
<tr><td>screen</td><td>Yes</td><td>No</td><td>string</td><td>Create the screen before executing `rc.lua` (`on` or `off`)</td></tr>
|
||||
<tr><td>replace</td><td>No</td><td>No</td><td>N/A</td><td>Replace the current window manager.</td></tr>
|
||||
</table>
|
||||
|
||||
A `modeline` must be near the top of `rc.lua` and start with `-- awesome_mode:`.
|
||||
The options are separated by `:`. If an option has a value, it is separated by
|
||||
`=`. The default modeline is:
|
||||
|
||||
-- awesome_mode: api-level=4:screen=on
|
||||
|
||||
To display more deprecation errors, you can increase the API level by 2:
|
||||
|
||||
-- awesome_mode: api-level=6:screen=on
|
||||
|
||||
## #! (shebang) support.
|
||||
|
||||
It is possible to make some `.lua` file executable and use the POSIX magic
|
||||
prefix (`#!`, often referred as the shebang operator). AwesomeWM will attempt
|
||||
to parse the header. Note that for now UTF-8 paths are not supported. A tipical
|
||||
file header will look like:
|
||||
|
||||
#! /usr/bin/env awesome --replace
|
||||
-- If LuaRocks is installed, make sure that packages installed through it
|
||||
-- are found (e.g. lgi). If LuaRocks is not installed, do nothing.
|
||||
pcall(require, "luarocks.loader")
|
||||
|
||||
-- Standard awesome library
|
||||
local gears = require("gears")
|
||||
[... more `rc.lua` content ...]
|
||||
|
||||
Then you can make the script executable with `chmod +x` and run it.
|
||||
|
||||
## Options description
|
||||
|
||||
### version (-v)
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>No</td>
|
||||
<td align='center'>No</td></tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The typical output will look like:
|
||||
|
||||
awesome v4.3 (Too long)
|
||||
• Compiled against Lua 5.1.5 (running with Lua 5.1)
|
||||
• API level: 4
|
||||
• D-Bus support: yes
|
||||
• xcb-errors support: no
|
||||
• execinfo support: yes
|
||||
• xcb-randr version: 1.6
|
||||
• LGI version: 0.9.2
|
||||
• Transparency enabled: yes
|
||||
• Custom search paths: no
|
||||
|
||||
The content is useful when reporting a bug.
|
||||
|
||||
### config (-c): Alternate config path.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>No</td>
|
||||
<td align='center'>No</td></tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This option allows to pass an arbitrary Lua file to be used as a config rather
|
||||
than `~/.config/awesome/rc.lua` or `/etc/xdg/awesome/rc.lua`. It makes zero
|
||||
sense in the shebang since you invoke a script directly. It doesn't make sense
|
||||
in the modeline either since at that point the file is already being read.
|
||||
|
||||
### force (-f): Use the command line arguments even when the modeline disagree.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>No</td>
|
||||
<td align='center'>No</td></tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Usually, modeslines have the final say of which options to enable. This allows
|
||||
`rc.lua` to be portable between computers without have to modify `~/.xinitrc`
|
||||
or your session files. However, sometime, it is useful to override these
|
||||
parameters. The most common use case is the to bump the API level to see more
|
||||
deprecation warnings.
|
||||
|
||||
### search (-s): Add directories to the Lua search paths.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This option allows to add more paths to the Lua search path. It can be used
|
||||
to set an alternate version of the core libraries such as `awful` to make
|
||||
upstream patches development easier. It can also be used to point to custom
|
||||
modules. It is usually recommended to place custom modules in
|
||||
`~/.config/awesome/` or `/usr/share/awesome/lib`. Again, this option is mostly
|
||||
useful for development.
|
||||
|
||||
### check (-k): Check the config **SYNTAX**.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>No</td>
|
||||
<td align='center'>No</td></tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This option only check if the file is a valid Lua script. It will not check if
|
||||
your custom logic makes sense. Even when this options says your config is fine,
|
||||
it does **NOT** mean it can load properly. It only means it can be parsed and
|
||||
the interpreter can attempt to execute it.
|
||||
|
||||
### no-argb (-a): Mitigate buggy graphics drivers.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This options disable the built-in real transparency support. This means
|
||||
titlebars and wiboxes can no longer be made fully transparent. If you don't
|
||||
use a compositing manager such as `compton` or `picom`, this will only improve
|
||||
reliability and portability. Transparency is enabled by default and this should
|
||||
only be used when your config misbehave with a popular graphics driver. If it
|
||||
does, please notify them. The bug is on their side.
|
||||
|
||||
### api-level (-l): Force your config to use a different API version.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If you invested a lot of effort into a configuration and a new major version
|
||||
is AwesomeWM is released, you might want to postpone having to update everything
|
||||
until you are ready to begin using the new features. If the API level is set,
|
||||
AwesomeWM will try to honor the behavior and content of the previous APIs.
|
||||
|
||||
You can also set this value forward to get notified faster of your usage of
|
||||
newly deprecated API and enjoy cutting edge experimental features.
|
||||
|
||||
The default API level matches the first component of the AwesomeWM version.
|
||||
For example, AwesomeWM v4.3 API level is "4". This only goes back to AwesomeWM
|
||||
4.0. The older 3.x APIs have been removed.
|
||||
|
||||
### screen (-m): Set the screen creation behavior.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This option changes *when* screen objects are created. In AwesomeWM 4.x, by
|
||||
default, they are created before `rc.lua` is parsed. This is very convenient
|
||||
for setup where the number of screen never changes. By creating them before
|
||||
`rc.lua`, it is possible to make many assumptions such as `mouse.screen` and
|
||||
`awful.screen.focused()` to always point to a valid screen. This is the `on`
|
||||
behavior. The main downside is that when the number of screen changes or when
|
||||
the DPI must be modified, all the automatic magic becomes very inconvenient.
|
||||
|
||||
When set to `off`, the screens are created early when executing `rc.lua`. This
|
||||
has the advantages of sending multiple signals and giving a lot more
|
||||
configuration options for features like the DPI or ultra-wide monitor. It also
|
||||
make it easier to add and remove screens dynamically since they are fully. In
|
||||
the future, the default will be `off` to allow HiDPI support to be enabled by
|
||||
default.
|
||||
controllable by Lua code.
|
||||
|
||||
### replace (-r): Replace the current window manager with AwesomeWM.
|
||||
|
||||
<table class='widget_list' border=1>
|
||||
<tr style='font-weight: bold;'>
|
||||
<th align='center'>Command line</th>
|
||||
<th align='center'>Modeline</th>
|
||||
<th align='center'>Shebang</th>
|
||||
<tr>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
<td align='center'>Yes</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
If this option is set, AwesomeWM will kill the current window manager (even
|
||||
if it is another `awesome` instance and replace it. This is disabled by default.
|
|
@ -38,6 +38,7 @@ topics={
|
|||
'05-awesomerc.md',
|
||||
'06-appearance.md',
|
||||
'07-my-first-awesome.md',
|
||||
'09-options.md',
|
||||
'16-using-cairo.md',
|
||||
'17-porting-tips.md',
|
||||
'90-FAQ.md',
|
||||
|
|
|
@ -126,6 +126,10 @@ typedef struct
|
|||
bool have_xkb;
|
||||
/** Check for XFixes extension */
|
||||
bool have_xfixes;
|
||||
/** Custom searchpaths are present, the runtime is tinted */
|
||||
bool have_searchpaths;
|
||||
/** When --no-argb is used in the modeline or command line */
|
||||
bool had_overriden_depth;
|
||||
uint8_t event_base_shape;
|
||||
uint8_t event_base_xkb;
|
||||
uint8_t event_base_randr;
|
||||
|
@ -224,6 +228,8 @@ typedef struct
|
|||
xcb_generic_event_t *pending_event;
|
||||
/** The exit code that main() will return with */
|
||||
int exit_code;
|
||||
/** The Global API level */
|
||||
int api_level;
|
||||
} awesome_t;
|
||||
|
||||
extern awesome_t globalconf;
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
---------------------------------------------------------------------------
|
||||
require("awful.permissions._common")._deprecated_autofocus_in_use()
|
||||
|
||||
--require("gears.debug").deprecate(
|
||||
-- "The `awful.autofocus` module is deprecated, remove the require() and "..
|
||||
-- "look at the new `rc.lua` granted permission section in the client rules",
|
||||
-- {deprecated_in=5}
|
||||
--)
|
||||
if awesome.api_level > 4 then
|
||||
--TODO v5: Remove `require("awful.autofocus")` from `rc.lua`.
|
||||
require("gears.debug").deprecate(
|
||||
"The `awful.autofocus` module is deprecated, remove the require() and "..
|
||||
"look at the new `rc.lua` granted permission section in the client rules",
|
||||
{deprecated_in=5}
|
||||
)
|
||||
end
|
||||
|
|
|
@ -740,9 +740,14 @@ screen.connect_signal("property::workarea", function(s)
|
|||
end)
|
||||
|
||||
-- Enable sloppy focus, so that focus follows mouse.
|
||||
client.connect_signal("mouse::enter", function(c)
|
||||
c:emit_signal("request::autoactivate", "mouse_enter", {raise=false})
|
||||
end)
|
||||
if awesome.api_level > 4 then
|
||||
--TODO v5: Remove the code from `rc.lua`. It cannot be done yet because we
|
||||
-- cannot know if the user removed it to disable sloppy focus or because
|
||||
-- they want to use the permissions to manage it.
|
||||
client.connect_signal("mouse::enter", function(c)
|
||||
c:emit_signal("request::autoactivate", "mouse_enter", {raise=false})
|
||||
end)
|
||||
end
|
||||
|
||||
return permissions
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ local displayed_deprecations = {}
|
|||
--- Display a deprecation notice, but only once per traceback.
|
||||
--
|
||||
-- This function also emits the `debug::deprecation` signal on the `awesome`
|
||||
-- global object.
|
||||
-- global object. If the deprecated API has been deprecated for more than one
|
||||
-- API level, it will also send a non-fatal error.
|
||||
--
|
||||
-- @param[opt] see The message to a new method / function to use.
|
||||
-- @tparam table args Extra arguments
|
||||
|
@ -90,17 +91,18 @@ local displayed_deprecations = {}
|
|||
-- @tparam integer args.deprecated_in Print the message only when Awesome's
|
||||
-- version is equal to or greater than deprecated_in.
|
||||
-- @staticfct gears.debug.deprecate
|
||||
-- @emits debug::deprecation
|
||||
-- @emitstparam @emitstparam string msg The full formatted message.
|
||||
-- @emitstparam @emitstparam string see A message provided by the caller.
|
||||
-- @emitstparam @emitstparam table args Some extra context.
|
||||
-- @emits debug::deprecation This is usually routed to stdout when the API is
|
||||
-- newly deprecated.
|
||||
-- @emitstparam debug::deprecation string msg The full formatted message.
|
||||
-- @emitstparam debug::deprecation string see A message provided by the caller.
|
||||
-- @emitstparam debug::deprecation table args Some extra context.
|
||||
-- @emits debug::error When the API has been deprecated for more than
|
||||
-- one API level.
|
||||
-- @emitstparam debug::error string msg The full formatted message.
|
||||
function debug.deprecate(see, args)
|
||||
args = args or {}
|
||||
if args.deprecated_in then
|
||||
local dep_ver = "v" .. tostring(args.deprecated_in)
|
||||
if awesome.version < dep_ver then
|
||||
return
|
||||
end
|
||||
if args.deprecated_in and awesome.api_level < args.deprecated_in then
|
||||
return
|
||||
end
|
||||
local tb = _G.debug.traceback()
|
||||
if displayed_deprecations[tb] then
|
||||
|
@ -123,9 +125,15 @@ function debug.deprecate(see, args)
|
|||
end
|
||||
debug.print_warning(msg .. ".\n" .. tb)
|
||||
|
||||
if awesome then
|
||||
if awesome and awesome.api_level == args.deprecated_in then
|
||||
awesome.emit_signal("debug::deprecation", msg, see, args)
|
||||
end
|
||||
|
||||
if args.deprecated_in and awesome.api_level > args.deprecated_in then
|
||||
awesome.emit_signal(
|
||||
"debug::error", msg, false
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
--- Create a class proxy with deprecation messages.
|
||||
|
@ -140,11 +148,8 @@ end
|
|||
-- @staticfct gears.debug.deprecate_class
|
||||
function debug.deprecate_class(fallback, old_name, new_name, args)
|
||||
args = args or {}
|
||||
if args.deprecated_in then
|
||||
local dep_ver = "v" .. tostring(args.deprecated_in)
|
||||
if awesome.version < dep_ver then
|
||||
return fallback
|
||||
end
|
||||
if args.deprecated_in and awesome.api_level < args.deprecated_in then
|
||||
return fallback
|
||||
end
|
||||
|
||||
local message = old_name.." has been renamed to "..new_name
|
||||
|
|
37
luaa.c
37
luaa.c
|
@ -540,15 +540,42 @@ static int luaA_get_active_modifiers(lua_State *L)
|
|||
}
|
||||
|
||||
/**
|
||||
* The version of awesome.
|
||||
* The AwesomeWM version.
|
||||
* @tfield string version
|
||||
*/
|
||||
|
||||
/**
|
||||
* The release name of awesome.
|
||||
* The AwesomeWM release name.
|
||||
* @tfield string release
|
||||
*/
|
||||
|
||||
/**
|
||||
* The AwesomeWM API level.
|
||||
*
|
||||
* By default, this matches the major version (first component of the version).
|
||||
*
|
||||
* API levels are used to allow newer version of AwesomeWM to alter the behavior
|
||||
* and subset deprecated APIs. Using an older API level than the current major
|
||||
* version allows to use legacy `rc.lua` with little porting. However, they wont
|
||||
* be able to use all the new features. Attempting to use a newer feature along
|
||||
* with an older API level is not and will not be supported, even if it almost
|
||||
* works. Keeping up to date with the newer API levels is highly recommended.
|
||||
*
|
||||
* Going the other direction, setting an higher API level allows to take
|
||||
* advantage of experimental feature. It will also be much harsher when it comes
|
||||
* to deprecation. Setting the API level value beyond `current+3` will treat
|
||||
* using APIs currently pending deprecation as fatal errors. All new code
|
||||
* submitted to the upstream AwesomeWM codebase is forbidden to use deprecated
|
||||
* APIs. Testing your patches with mode and the default config is recommended
|
||||
* before submitting a patch.
|
||||
*
|
||||
* You can use the `-l` command line option or `api-level` modeline key to set
|
||||
* the API level for your `rc.lua`. This setting is global and read only,
|
||||
* individual modules cannot set their own API level.
|
||||
*
|
||||
* @tfield string api_level
|
||||
*/
|
||||
|
||||
/**
|
||||
* The configuration file which has been loaded.
|
||||
* @tfield string conffile
|
||||
|
@ -616,6 +643,12 @@ luaA_awesome_index(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if(A_STREQ(buf, "api_level"))
|
||||
{
|
||||
lua_pushinteger(L, globalconf.api_level);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(A_STREQ(buf, "startup"))
|
||||
{
|
||||
lua_pushboolean(L, globalconf.loop == NULL);
|
||||
|
|
|
@ -0,0 +1,466 @@
|
|||
/*
|
||||
* stack.h - client stack management header
|
||||
*
|
||||
* Copyright © 2020 Emmanuel Lepage-Vallee <elv1313@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "options.h"
|
||||
#include "common/version.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define KEY_VALUE_BUF_MAX 64
|
||||
#define READ_BUF_MAX 127
|
||||
|
||||
static void
|
||||
set_api_level(char *value)
|
||||
{
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
char *ptr;
|
||||
int ret = strtol(value, &ptr, 10);
|
||||
|
||||
/* There is no valid number at all */
|
||||
if (value == ptr) {
|
||||
fprintf(stderr, "Invalid API level %s\n", value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* There is a number, but also letters, this is invalid */
|
||||
if (ptr[0] != '\0' && ptr[0] != '.') {
|
||||
fprintf(stderr, "Invalid API level %s\n", value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This API level doesn't exist, fallback to v4 */
|
||||
if (ret < 4)
|
||||
ret = 4;
|
||||
|
||||
globalconf.api_level = ret;
|
||||
}
|
||||
|
||||
static void
|
||||
push_arg(string_array_t *args, char *value, size_t *len)
|
||||
{
|
||||
value[*len] = '\0';
|
||||
string_array_append(args, a_strdup(value));
|
||||
(*len) = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Support both shebang and modeline modes.
|
||||
*/
|
||||
bool
|
||||
options_init_config(char *execpath, char *configpath, int *init_flags, string_array_t *paths)
|
||||
{
|
||||
/* The different state the parser can have. */
|
||||
enum {
|
||||
MODELINE_STATE_INIT , /* Start of line */
|
||||
MODELINE_STATE_NEWLINE , /* Start of line */
|
||||
MODELINE_STATE_COMMENT , /* until -- */
|
||||
MODELINE_STATE_MODELINE , /* until awesome_mode: */
|
||||
MODELINE_STATE_SHEBANG , /* until ! */
|
||||
MODELINE_STATE_KEY_DELIM , /* until the key begins */
|
||||
MODELINE_STATE_KEY , /* until '=' */
|
||||
MODELINE_STATE_VALUE_DELIM, /* after ':' */
|
||||
MODELINE_STATE_VALUE , /* until ',' or '\n' */
|
||||
MODELINE_STATE_COMPLETE , /* Parsing is done */
|
||||
MODELINE_STATE_INVALID , /* note a modeline */
|
||||
MODELINE_STATE_ERROR /* broken modeline */
|
||||
} state = MODELINE_STATE_INIT;
|
||||
|
||||
/* The parsing mode */
|
||||
enum {
|
||||
MODELINE_MODE_NONE , /* No modeline */
|
||||
MODELINE_MODE_LINE , /* modeline */
|
||||
MODELINE_MODE_SHEBANG, /* #! shebang */
|
||||
} mode = MODELINE_MODE_NONE;
|
||||
|
||||
static const unsigned char name[] = "awesome_mode:";
|
||||
static char key_buf [KEY_VALUE_BUF_MAX+1] = {'\0'};
|
||||
static char file_buf[READ_BUF_MAX+1 ] = {'\0'};
|
||||
size_t pos = 0;
|
||||
|
||||
string_array_t argv;
|
||||
string_array_init(&argv);
|
||||
string_array_append(&argv, a_strdup(execpath));
|
||||
|
||||
FILE *fp = fopen(configpath, "r");
|
||||
|
||||
/* Share the error codepath with parsing errors */
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
/* Try to read the first line */
|
||||
if (!fgets(file_buf, READ_BUF_MAX, fp)) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char c;
|
||||
|
||||
/* Simple state machine to translate both modeline and shebang into argv */
|
||||
for (int i = 0; (c = file_buf[i++]) != '\0';) {
|
||||
/* Be very permissive, skip the unknown, UTF is not allowed */
|
||||
if ((c > 126 || c < 32) && c != 10 && c != 13 && c != 9) {
|
||||
static bool once = true;
|
||||
/* Print a warning once */
|
||||
if (once) {
|
||||
fprintf(stderr, "WARNING: modelines must use ASCII\n");
|
||||
once = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case MODELINE_STATE_INIT:
|
||||
switch (c) {
|
||||
case '#':
|
||||
state = MODELINE_STATE_SHEBANG;
|
||||
break;
|
||||
case ' ': case '-':
|
||||
state = MODELINE_STATE_COMMENT;
|
||||
break;
|
||||
default:
|
||||
state = MODELINE_STATE_INVALID;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_NEWLINE:
|
||||
switch (c) {
|
||||
case ' ': case '-':
|
||||
state = MODELINE_STATE_COMMENT;
|
||||
break;
|
||||
default:
|
||||
state = MODELINE_STATE_INVALID;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_COMMENT:
|
||||
switch (c) {
|
||||
case '-':
|
||||
state = MODELINE_STATE_MODELINE;
|
||||
break;
|
||||
default:
|
||||
state = MODELINE_STATE_INVALID;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_MODELINE:
|
||||
if (c == ' ')
|
||||
break;
|
||||
else if (c != name[pos++]) {
|
||||
state = MODELINE_STATE_INVALID;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
if (pos == 13) {
|
||||
pos = 0;
|
||||
state = MODELINE_STATE_KEY_DELIM;
|
||||
mode = MODELINE_MODE_LINE;
|
||||
}
|
||||
|
||||
break;
|
||||
case MODELINE_STATE_SHEBANG:
|
||||
switch(c) {
|
||||
case '!':
|
||||
mode = MODELINE_MODE_SHEBANG;
|
||||
state = MODELINE_STATE_KEY_DELIM;
|
||||
break;
|
||||
default:
|
||||
state = MODELINE_STATE_INVALID;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_KEY_DELIM:
|
||||
switch (c) {
|
||||
case ' ': case '\t': case ':': case '=':
|
||||
break;
|
||||
case '\n': case '\r':
|
||||
state = MODELINE_STATE_ERROR;
|
||||
break;
|
||||
default:
|
||||
/* In modeline mode, assume all keys are the long name */
|
||||
switch(mode) {
|
||||
case MODELINE_MODE_LINE:
|
||||
strcpy(key_buf, "--");
|
||||
pos = 2;
|
||||
break;
|
||||
case MODELINE_MODE_SHEBANG:
|
||||
case MODELINE_MODE_NONE:
|
||||
break;
|
||||
};
|
||||
state = MODELINE_STATE_KEY;
|
||||
key_buf[pos++] = c;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_KEY:
|
||||
switch (c) {
|
||||
case '=':
|
||||
push_arg(&argv, key_buf, &pos);
|
||||
state = MODELINE_STATE_VALUE_DELIM;
|
||||
break;
|
||||
case ' ': case '\t': case ':':
|
||||
push_arg(&argv, key_buf, &pos);
|
||||
state = MODELINE_STATE_KEY_DELIM;
|
||||
break;
|
||||
default:
|
||||
key_buf[pos++] = c;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_VALUE_DELIM:
|
||||
switch (c) {
|
||||
case ' ': case '\t':
|
||||
break;
|
||||
case '\n': case '\r':
|
||||
state = MODELINE_STATE_ERROR;
|
||||
break;
|
||||
case ':':
|
||||
state = MODELINE_STATE_KEY_DELIM;
|
||||
break;
|
||||
default:
|
||||
state = MODELINE_STATE_VALUE;
|
||||
key_buf[pos++] = c;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_VALUE:
|
||||
switch(c) {
|
||||
case ',': case ' ': case ':': case '\t':
|
||||
push_arg(&argv, key_buf, &pos);
|
||||
state = MODELINE_STATE_KEY_DELIM;
|
||||
break;
|
||||
case '\n': case '\r':
|
||||
state = MODELINE_STATE_COMPLETE;
|
||||
break;
|
||||
default:
|
||||
key_buf[pos++] = c;
|
||||
}
|
||||
break;
|
||||
case MODELINE_STATE_INVALID:
|
||||
/* This cannot happen, the `if` below should prevent it */
|
||||
state = MODELINE_STATE_ERROR;
|
||||
break;
|
||||
case MODELINE_STATE_COMPLETE:
|
||||
case MODELINE_STATE_ERROR:
|
||||
break;
|
||||
}
|
||||
|
||||
/* No keys or values are that large */
|
||||
if (pos >= KEY_VALUE_BUF_MAX)
|
||||
state = MODELINE_STATE_ERROR;
|
||||
|
||||
/* Stop parsing when completed */
|
||||
if (state == MODELINE_STATE_ERROR || state == MODELINE_STATE_COMPLETE)
|
||||
break;
|
||||
|
||||
/* Try the next line */
|
||||
if (((i == READ_BUF_MAX || file_buf[i+1] == '\0') && !feof(fp)) || state == MODELINE_STATE_INVALID) {
|
||||
if (state == MODELINE_STATE_KEY || state == MODELINE_STATE_VALUE)
|
||||
push_arg(&argv, key_buf, &pos);
|
||||
|
||||
/* Skip empty lines */
|
||||
do {
|
||||
if (fgets(file_buf, READ_BUF_MAX, fp))
|
||||
state = MODELINE_STATE_NEWLINE;
|
||||
else {
|
||||
state = argv.len ? MODELINE_STATE_COMPLETE : MODELINE_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
i = 0; /* Always reset `i` to avoid an unlikely invalid read */
|
||||
} while (i == 0 && file_buf[0] == '\n');
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
/* Reset the global POSIX args counter */
|
||||
optind = 0;
|
||||
|
||||
/* Be future proof, allow let unknown keys live, let the Lua code decide */
|
||||
(*init_flags) |= INIT_FLAG_ALLOW_FALLBACK;
|
||||
|
||||
options_check_args(argv.len, argv.tab, init_flags, paths);
|
||||
|
||||
/* Cleanup */
|
||||
string_array_wipe(&argv);
|
||||
|
||||
return state == MODELINE_STATE_COMPLETE;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
options_detect_shebang(int argc, char **argv)
|
||||
{
|
||||
/* There is no cross-platform ways to check if it is *really* called by a
|
||||
* shebang. There is a couple Linux specific hacks which work with the
|
||||
* most common C libraries, but they wont work on *BSD.
|
||||
*
|
||||
* On some platforms, the argv is going to be parsed by the OS, in other
|
||||
* they will be concatenated in one big string. There is some ambiguities
|
||||
* caused by that. For example, `awesome -s foo` and and `#!/bin/awesome -s`
|
||||
* are both technically valid if `foo` is a directory in the first and
|
||||
* lua file (without extension) in the second. While `-s` with a file
|
||||
* wont work, it is hard to know by looking at the string.
|
||||
*
|
||||
* The trick to avoid any ambiguity is to just read the file and see if
|
||||
* the args match. `options_init_config` will be called later and the args
|
||||
* will be parsed properly.
|
||||
*/
|
||||
|
||||
/* On WSL and some other *nix this isn't true, but it is true often enough */
|
||||
if (argc > 3 || argc == 1)
|
||||
return NULL;
|
||||
|
||||
/* Check if it is executable */
|
||||
struct stat inf;
|
||||
if (stat(argv[argc-1], &inf) || !(inf.st_mode & S_IXUSR))
|
||||
return NULL;
|
||||
|
||||
FILE *fp = fopen(argv[argc-1], "r");
|
||||
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
char buf[3];
|
||||
|
||||
if (!fgets(buf, 2, fp)) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (!strcmp(buf, "#!"))
|
||||
return NULL;
|
||||
|
||||
/* Ok, good enough, this is a shebang script, assume it called `awesome` */
|
||||
return a_strdup(argv[argc-1]);
|
||||
}
|
||||
|
||||
/** Print help and exit(2) with given exit_code.
|
||||
* \param exit_code The exit code.
|
||||
*/
|
||||
static void __attribute__ ((noreturn))
|
||||
exit_help(int exit_code)
|
||||
{
|
||||
FILE *outfile = (exit_code == EXIT_SUCCESS) ? stdout : stderr;
|
||||
fprintf(outfile,
|
||||
"Usage: awesome [OPTION]\n\
|
||||
-h, --help show help\n\
|
||||
-v, --version show version\n\
|
||||
-c, --config FILE configuration file to use\n\
|
||||
-f, --force ignore modelines and apply the command line arguments\n\
|
||||
-s, --search DIR add a directory to the library search path\n\
|
||||
-k, --check check configuration file syntax\n\
|
||||
-a, --no-argb disable client transparency support\n\
|
||||
-l --api-level LEVEL select a different API support level than the current version \n\
|
||||
-m, --screen on|off enable or disable automatic screen creation (default: on)\n\
|
||||
-r, --replace replace an existing window manager\n");
|
||||
exit(exit_code);
|
||||
}
|
||||
|
||||
#define ARG 1
|
||||
#define NO_ARG 0
|
||||
|
||||
char *
|
||||
options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths)
|
||||
{
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{ "help" , NO_ARG, NULL, 'h' },
|
||||
{ "version" , NO_ARG, NULL, 'v' },
|
||||
{ "config" , ARG , NULL, 'c' },
|
||||
{ "force" , NO_ARG, NULL, 'f' },
|
||||
{ "check" , NO_ARG, NULL, 'k' },
|
||||
{ "search" , ARG , NULL, 's' },
|
||||
{ "no-argb" , NO_ARG, NULL, 'a' },
|
||||
{ "replace" , NO_ARG, NULL, 'r' },
|
||||
{ "screen" , ARG , NULL, 'm' },
|
||||
{ "api-level" , ARG , NULL, 'l' },
|
||||
{ "reap" , ARG , NULL, '\1' },
|
||||
{ NULL , NO_ARG, NULL, 0 }
|
||||
};
|
||||
|
||||
char *confpath = NULL;
|
||||
int opt;
|
||||
|
||||
while((opt = getopt_long(argc, argv, "vhkc:arml:",
|
||||
long_options, NULL)) != -1) {
|
||||
switch(opt)
|
||||
{
|
||||
case 'v':
|
||||
eprint_version();
|
||||
break;
|
||||
case 'h':
|
||||
if (! ((*init_flags) & INIT_FLAG_ALLOW_FALLBACK))
|
||||
exit_help(EXIT_SUCCESS);
|
||||
break;
|
||||
case 'f':
|
||||
(*init_flags) |= INIT_FLAG_FORCE_CMD_ARGS;
|
||||
break;
|
||||
case 'k':
|
||||
(*init_flags) |= INIT_FLAG_RUN_TEST;
|
||||
break;
|
||||
case 'c':
|
||||
if (confpath != NULL)
|
||||
fatal("--config may only be specified once");
|
||||
confpath = a_strdup(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
/* Validation */
|
||||
if ((!optarg) || !(A_STREQ(optarg, "off") || A_STREQ(optarg, "on")))
|
||||
fatal("The possible values of -m/--screen are \"on\" or \"off\"");
|
||||
|
||||
globalconf.no_auto_screen = A_STREQ(optarg, "off");
|
||||
|
||||
(*init_flags) &= ~INIT_FLAG_AUTO_SCREEN;
|
||||
|
||||
break;
|
||||
case 's':
|
||||
globalconf.have_searchpaths = true;
|
||||
string_array_append(paths, a_strdup(optarg));
|
||||
break;
|
||||
case 'a':
|
||||
globalconf.had_overriden_depth = true;
|
||||
(*init_flags) &= ~INIT_FLAG_ARGB;
|
||||
break;
|
||||
case 'r':
|
||||
(*init_flags) |= INIT_FLAG_REPLACE_WM;
|
||||
break;
|
||||
case 'l':
|
||||
set_api_level(optarg);
|
||||
break;
|
||||
case '\1':
|
||||
/* Silently ignore --reap and its argument */
|
||||
break;
|
||||
default:
|
||||
if (! ((*init_flags) & INIT_FLAG_ALLOW_FALLBACK))
|
||||
exit_help(EXIT_FAILURE);
|
||||
break;
|
||||
}}
|
||||
|
||||
return confpath;
|
||||
}
|
||||
|
||||
#undef AR
|
||||
#undef NO_ARG
|
||||
#undef KEY_VALUE_BUF_MAX
|
||||
#undef READ_BUF_MAX
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* stack.h - client stack management header
|
||||
*
|
||||
* Copyright © 2020 Emmanuel Lepage-Vallee <elv1313@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
#include "common/array.h"
|
||||
#include "globalconf.h"
|
||||
|
||||
/**
|
||||
* Initialization values extracted from the command line or modeline.
|
||||
*/
|
||||
typedef enum {
|
||||
INIT_FLAG_NONE = 0x0,
|
||||
INIT_FLAG_RUN_TEST = 0x1,
|
||||
INIT_FLAG_ARGB = 0x1 << 1,
|
||||
INIT_FLAG_REPLACE_WM = 0x1 << 2,
|
||||
INIT_FLAG_AUTO_SCREEN = 0x1 << 3,
|
||||
INIT_FLAG_ALLOW_FALLBACK = 0x1 << 4,
|
||||
INIT_FLAG_FORCE_CMD_ARGS = 0x1 << 5,
|
||||
} awesome_init_config_t;
|
||||
|
||||
char *options_detect_shebang(int argc, char **argv);
|
||||
bool options_init_config(char *execpath, char *configpath, int *init_flags, string_array_t *paths);
|
||||
char *options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths);
|
|
@ -15,6 +15,7 @@ describe("awful.permissions.client_geometry_requests", function()
|
|||
connect_signal = function() end,
|
||||
}
|
||||
_G.awesome = {
|
||||
api_level = 4,
|
||||
connect_signal = function() end,
|
||||
}
|
||||
_G.drawin = {
|
||||
|
|
|
@ -83,7 +83,8 @@ function awesome.xrdb_get_value()
|
|||
end
|
||||
|
||||
-- Always show deprecated messages
|
||||
awesome.version = "v9999"
|
||||
awesome.version = "v9999"
|
||||
awesome.api_level = 9999
|
||||
|
||||
-- SVG are composited. Without it we need a root surface
|
||||
awesome.composite_manager_running = true
|
||||
|
|
|
@ -115,7 +115,7 @@ fi
|
|||
# shellcheck disable=SC2206
|
||||
awesome_options=($AWESOME_OPTIONS $manual_screens --search lib --search "$this_dir")
|
||||
|
||||
awesome_options+=(--screen off)
|
||||
awesome_options+=(--screen off --force)
|
||||
|
||||
# Cleanup on errors / aborting.
|
||||
cleanup() {
|
||||
|
|
Loading…
Reference in New Issue