init: Add an API level concept to `capi`.
The API level concept is something used by other projects such as Android and iOS to allow deprecated features to be removed and the bahavior to be altered without breaking compability with existing code. The same will apply to AwesomeWM. The current API level is "4" and as long as config use this, no deprecation or bahavior change will be exposed. If the user sets it to an higher value or we release the next major version and new users start to use the, then current, default config, they will use the new API level. The the far future, if ever, we could fork the entire Lua libraries to support legacy APIs. This would only require to keep the core API support for those legacy calls. In the meantime, `gears.debug` will use this to manage the deprecation and some conditional code will be added as a last resort attempt to preserve behavior compatibility while moving forward with breaking changes.
This commit is contained in:
parent
d2f8999595
commit
ee80fe052f
|
@ -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_
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
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);
|
||||
|
|
76
options.c
76
options.c
|
@ -24,12 +24,41 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue