diff --git a/awesome-version-internal.h b/awesome-version-internal.h index 173c2d3c..395d143d 100644 --- a/awesome-version-internal.h +++ b/awesome-version-internal.h @@ -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_ diff --git a/awesome.c b/awesome.c index ba9c8151..c71699d9 100644 --- a/awesome.c +++ b/awesome.c @@ -580,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); diff --git a/awesomeConfig.cmake b/awesomeConfig.cmake index 4592001c..3cf42b11 100644 --- a/awesomeConfig.cmake +++ b/awesomeConfig.cmake @@ -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) diff --git a/common/version.c b/common/version.c index aae63fdb..c32fa3cd 100644 --- a/common/version.c +++ b/common/version.c @@ -100,4 +100,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 diff --git a/common/version.h b/common/version.h index 7bf3bc90..776df558 100644 --- a/common/version.h +++ b/common/version.h @@ -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 diff --git a/globalconf.h b/globalconf.h index cf55493b..990700d0 100644 --- a/globalconf.h +++ b/globalconf.h @@ -224,6 +224,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; diff --git a/luaa.c b/luaa.c index 3e9455f7..a5cb333a 100644 --- a/luaa.c +++ b/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); diff --git a/options.c b/options.c index 380c7b52..dc9b760d 100644 --- a/options.c +++ b/options.c @@ -24,12 +24,41 @@ #include #include +#include #include #include #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) { @@ -327,15 +356,16 @@ 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\ - -f, --force ignore modelines and apply the command line arguments\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"); + -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\ + --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); } @@ -348,23 +378,24 @@ 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' }, - { "reap", ARG , NULL, '\1' }, - { NULL, NO_ARG, NULL, 0 } + { "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:arm:", + while((opt = getopt_long(argc, argv, "vhkc:arml:", long_options, NULL)) != -1) { switch(opt) { @@ -405,6 +436,9 @@ options_check_args(int argc, char **argv, int *init_flags, string_array_t *paths 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; diff --git a/tests/examples/shims/awesome.lua b/tests/examples/shims/awesome.lua index ac403572..64b0da43 100644 --- a/tests/examples/shims/awesome.lua +++ b/tests/examples/shims/awesome.lua @@ -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